// Copyright 2025 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "src/dawn/native/webgpu/ToWGPU.h"

#include "dawn/native/dawn_platform_autogen.h"
#include "src/dawn/common/Math.h"
#include "src/dawn/common/StringViewUtils.h"
#include "src/dawn/native/BlockInfo.h"
#include "src/dawn/native/Commands.h"
#include "src/dawn/native/webgpu/BufferWGPU.h"
#include "src/dawn/native/webgpu/Forward.h"
#include "src/dawn/native/webgpu/QuerySetWGPU.h"
#include "src/dawn/native/webgpu/TextureWGPU.h"

namespace dawn::native::webgpu {

WGPUExtent3D ToWGPU(const TexelExtent3D& extent) {
    return {
        .width = dchecked_cast<uint32_t>(extent.width),
        .height = dchecked_cast<uint32_t>(extent.height),
        .depthOrArrayLayers = dchecked_cast<uint32_t>(extent.depthOrArrayLayers),
    };
}

WGPUOrigin3D ToWGPU(const TexelOrigin3D& origin) {
    return {
        .x = dchecked_cast<uint32_t>(origin.x),
        .y = dchecked_cast<uint32_t>(origin.y),
        .z = dchecked_cast<uint32_t>(origin.z),
    };
}

WGPUOrigin2D ToWGPU(const Origin2D& origin) {
    return {
        .x = static_cast<uint32_t>(origin.x),
        .y = static_cast<uint32_t>(origin.y),
    };
}

WGPUExtent2D ToWGPU(const Extent2D& extent) {
    return {
        .width = static_cast<uint32_t>(extent.width),
        .height = static_cast<uint32_t>(extent.height),
    };
}

WGPUColor ToWGPU(const dawn::native::Color& color) {
    return {
        .r = color.r,
        .g = color.g,
        .b = color.b,
        .a = color.a,
    };
}

WGPUTexelCopyBufferLayout ToWGPU(const TexelCopyBufferLayout& copy) {
    return {
        .offset = copy.offset,
        .bytesPerRow = copy.bytesPerRow,
        .rowsPerImage = copy.rowsPerImage,
    };
}

WGPUTexelCopyBufferInfo ToWGPU(const BufferCopy& copy, const TypedTexelBlockInfo& blockInfo) {
    return {
        .layout =
            {
                .offset = copy.offset,
                .bytesPerRow = static_cast<uint32_t>(blockInfo.ToBytes(copy.blocksPerRow)),
                .rowsPerImage = dchecked_cast<uint32_t>(copy.rowsPerImage),
            },
        .buffer = ToBackend(copy.buffer)->GetInnerHandle(),
    };
}

WGPUTexelCopyBufferInfo ToWGPU(const TexelCopyBufferLayout& copy, const BufferBase* buffer) {
    return {
        .layout = ToWGPU(copy),
        .buffer = ToBackend(buffer)->GetInnerHandle(),
    };
}

WGPUTextureAspect ToWGPU(const Aspect aspect) {
    switch (aspect) {
        case Aspect::Depth:
            return WGPUTextureAspect_DepthOnly;
        case Aspect::Stencil:
            return WGPUTextureAspect_StencilOnly;
        case Aspect::Plane0:
            return WGPUTextureAspect_Plane0Only;
        case Aspect::Plane1:
            return WGPUTextureAspect_Plane1Only;
        case Aspect::Plane2:
            return WGPUTextureAspect_Plane2Only;
        default:
            return WGPUTextureAspect_All;
    }
}

WGPULoadOp ToWGPU(const wgpu::LoadOp op) {
    switch (op) {
        case wgpu::LoadOp::Load:
            return WGPULoadOp_Load;
        case wgpu::LoadOp::Clear:
            return WGPULoadOp_Clear;
        case wgpu::LoadOp::ExpandResolveTexture:
            return WGPULoadOp_ExpandResolveTexture;
        default:
            return WGPULoadOp_Undefined;
    }
}

WGPUStoreOp ToWGPU(const wgpu::StoreOp op) {
    switch (op) {
        case wgpu::StoreOp::Store:
            return WGPUStoreOp_Store;
        case wgpu::StoreOp::Discard:
            return WGPUStoreOp_Discard;
        default:
            return WGPUStoreOp_Undefined;
    }
}

WGPUIndexFormat ToWGPU(const wgpu::IndexFormat format) {
    switch (format) {
        case wgpu::IndexFormat::Uint16:
            return WGPUIndexFormat_Uint16;
        case wgpu::IndexFormat::Uint32:
            return WGPUIndexFormat_Uint32;
        default:
            return WGPUIndexFormat_Undefined;
    }
}

WGPUPassTimestampWrites ToWGPU(const TimestampWrites& writes) {
    return {
        .nextInChain = nullptr,
        .querySet = ToBackend(writes.querySet)->GetInnerHandle(),
        .beginningOfPassWriteIndex = uint32_t{writes.beginningOfPassWriteIndex},
        .endOfPassWriteIndex = uint32_t{writes.endOfPassWriteIndex},
    };
}

WGPUTexelCopyTextureInfo ToWGPU(const TextureCopy& copy) {
    return {
        .texture = ToBackend(copy.texture)->GetInnerHandle(),
        .mipLevel = copy.mipLevel,
        .origin = ToWGPU(copy.origin),
        .aspect = ToWGPU(copy.aspect),
    };
}

WGPURenderPassColorAttachment ToWGPU(const RenderPassColorAttachmentInfo& info) {
    return {
        .nextInChain = nullptr,
        .view = ToBackend(info.view)->GetInnerHandle(),
        // depthSlice is set to 0 for undefined in native::CommandEncoder.
        .depthSlice =
            info.depthSlice == 0 && info.view->GetDimension() != wgpu::TextureViewDimension::e3D
                ? WGPU_DEPTH_SLICE_UNDEFINED
                : info.depthSlice,
        .resolveTarget = info.resolveTarget == nullptr
                             ? nullptr
                             : ToBackend(info.resolveTarget)->GetInnerHandle(),
        .loadOp = ToWGPU(info.loadOp),
        .storeOp = ToWGPU(info.storeOp),
        .clearValue = ToWGPU(info.clearColor),
    };
}

WGPURenderPassDepthStencilAttachment ToWGPU(const RenderPassDepthStencilAttachmentInfo& info) {
    // Depth and stencil op in info is set to default value is not explicitly assigned.
    // Avoid setting them if there's no such aspect or the aspect is read only.
    bool setDepthOp = !info.depthReadOnly && IsSubset(Aspect::Depth, info.view->GetAspects());
    bool setStencilOp = !info.stencilReadOnly && IsSubset(Aspect::Stencil, info.view->GetAspects());
    return {
        .nextInChain = nullptr,
        .view = info.view == nullptr ? nullptr : ToBackend(info.view)->GetInnerHandle(),
        .depthLoadOp = setDepthOp ? ToWGPU(info.depthLoadOp) : WGPULoadOp_Undefined,
        .depthStoreOp = setDepthOp ? ToWGPU(info.depthStoreOp) : WGPUStoreOp_Undefined,
        .depthClearValue = info.clearDepth,
        .depthReadOnly = info.depthReadOnly,
        .stencilLoadOp = setStencilOp ? ToWGPU(info.stencilLoadOp) : WGPULoadOp_Undefined,
        .stencilStoreOp = setStencilOp ? ToWGPU(info.stencilStoreOp) : WGPUStoreOp_Undefined,
        .stencilClearValue = info.clearStencil,
        .stencilReadOnly = info.stencilReadOnly,
    };
}

WGPUStencilFaceState ToWGPU(const StencilFaceState* desc) {
    return {
        .compare = ToAPI(desc->compare),
        .failOp = ToAPI(desc->failOp),
        .depthFailOp = ToAPI(desc->depthFailOp),
        .passOp = ToAPI(desc->passOp),
    };
}

WGPUDepthStencilState ToWGPU(const DepthStencilState* desc) {
    return {
        .nextInChain = nullptr,
        .format = ToAPI(desc->format),
        .depthWriteEnabled = desc->depthWriteEnabled,
        .depthCompare = ToAPI(desc->depthCompare),
        .stencilFront = ToWGPU(&desc->stencilFront),
        .stencilBack = ToWGPU(&desc->stencilBack),
        .stencilReadMask = desc->stencilReadMask,
        .stencilWriteMask = desc->stencilWriteMask,
        .depthBias = desc->depthBias,
        .depthBiasSlopeScale = desc->depthBiasSlopeScale,
        .depthBiasClamp = desc->depthBiasClamp,
    };
}

WGPUPrimitiveState ToWGPU(const PrimitiveState* desc) {
    return {
        .nextInChain = nullptr,
        .topology = ToAPI(desc->topology),
        .stripIndexFormat = ToAPI(desc->stripIndexFormat),
        .frontFace = ToAPI(desc->frontFace),
        .cullMode = ToAPI(desc->cullMode),
        .unclippedDepth = desc->unclippedDepth,
    };
}

WGPUMultisampleState ToWGPU(const MultisampleState* desc) {
    return {
        .nextInChain = nullptr,
        .count = desc->count,
        .mask = desc->mask,
        .alphaToCoverageEnabled = desc->alphaToCoverageEnabled,
    };
}

WGPUBlendState ToWGPU(const BlendState* desc) {
    return {
        .color =
            {
                .operation = ToAPI(desc->color.operation),
                .srcFactor = ToAPI(desc->color.srcFactor),
                .dstFactor = ToAPI(desc->color.dstFactor),
            },
        .alpha =
            {
                .operation = ToAPI(desc->alpha.operation),
                .srcFactor = ToAPI(desc->alpha.srcFactor),
                .dstFactor = ToAPI(desc->alpha.dstFactor),
            },
    };
}

void PopulateWGPUConstants(std::vector<WGPUConstantEntry>* constants,
                           std::vector<std::string>* keys,
                           const PipelineConstantEntries& entries) {
    keys->reserve(entries.size());
    constants->reserve(entries.size());
    for (const auto& [key, value] : entries) {
        keys->push_back(key);
        constants->push_back(WGPUConstantEntry{
            .nextInChain = nullptr,
            .key = ToOutputStringView(keys->back()),
            .value = value,
        });
    }
}

}  // namespace dawn::native::webgpu
