// 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/CaptureContext.h"

#include <concepts>
#include <vector>

#include "dawn/common/StringViewUtils.h"
#include "dawn/native/BlockInfo.h"
#include "dawn/native/CommandBuffer.h"
#include "dawn/native/Commands.h"
#include "dawn/native/Device.h"
#include "dawn/native/ObjectBase.h"
#include "dawn/native/webgpu/BufferWGPU.h"
#include "dawn/native/webgpu/DeviceWGPU.h"
#include "dawn/native/webgpu/QuerySetWGPU.h"
#include "dawn/native/webgpu/QueueWGPU.h"
#include "dawn/native/webgpu/Serialization.h"
#include "dawn/native/webgpu/TextureWGPU.h"

namespace dawn::native::webgpu {

CaptureContext::ScopedContentWriter::ScopedContentWriter(CaptureContext& context)
    : mContext(context) {}

CaptureContext::ScopedContentWriter::~ScopedContentWriter() {
    uint64_t offset = mBytesWritten % 4;
    if (offset) {
        static char zero[3] = {0};
        uint64_t paddingNeeded = 4 - offset;
        mContext.WriteContentBytes(zero, paddingNeeded);
    }
}

void CaptureContext::ScopedContentWriter::WriteContentBytes(const void* data, size_t size) {
    mContext.WriteContentBytes(data, size);
    mBytesWritten += size;
}

MaybeError CaptureContext::CaptureCreation(schema::ObjectId id,
                                           const std::string& label,
                                           RecordableObject* object) {
    schema::RootCommandCreateResourceCmd cmd{{
        .data = {{
            .resource = {{
                .type = object->GetObjectType(),
                .id = id,
                .label = label,
            }},
        }},
    }};
    Serialize(*this, cmd);
    return object->CaptureCreationParameters(*this);
}

CaptureContext::CaptureContext(Device* device,
                               std::ostream& commandStream,
                               std::ostream& contentStream)
    : mDevice(device), mCommandStream(commandStream), mContentStream(contentStream) {}

CaptureContext::~CaptureContext() {
    if (mCopyBuffer) {
        mDevice->wgpu.bufferDestroy(mCopyBuffer);
    }
}

WGPUBuffer CaptureContext::GetCopyBuffer() {
    if (!mCopyBuffer) {
        WGPUBufferDescriptor desc = {};
        // Add a label to the copy buffer for better debugging experience.
        desc.label = ToOutputStringView("Capture Copy Buffer");
        desc.size = kCopyBufferSize;
        desc.usage = WGPUBufferUsage_CopyDst | WGPUBufferUsage_MapRead;
        mCopyBuffer = mDevice->wgpu.deviceCreateBuffer(mDevice->GetInnerHandle(), &desc);
    }
    return mCopyBuffer;
}

void CaptureContext::WriteContentBytes(const void* data, size_t size) {
    mContentStream.write(reinterpret_cast<const char*>(data), size);
}

void CaptureContext::WriteCommandBytes(const void* data, size_t size) {
    mCommandStream.write(reinterpret_cast<const char*>(data), size);
    mCommandBytesWritten += size;
}

MaybeError CaptureContext::CaptureQueueWriteBuffer(Buffer* buffer,
                                                   uint64_t bufferOffset,
                                                   const void* data,
                                                   size_t size) {
    schema::ObjectId id;
    DAWN_TRY_ASSIGN(id, AddResourceAndGetId(buffer));
    schema::RootCommandWriteBufferCmd cmd{{
        .data = {{
            .bufferId = id,
            .bufferOffset = bufferOffset,
            .size = size,
        }},
    }};

    Serialize(*this, cmd);
    WriteContentBytes(data, size);
    return {};
}

MaybeError CaptureContext::CaptureUnmapBuffer(Buffer* buffer,
                                              uint64_t bufferOffset,
                                              const void* data,
                                              size_t size) {
    schema::ObjectId id;
    DAWN_TRY_ASSIGN(id, AddResourceAndGetId(buffer));
    schema::RootCommandUnmapBufferCmd cmd{{
        .data = {{
            .bufferId = id,
            .bufferOffset = bufferOffset,
            .size = size,
        }},
    }};

    Serialize(*this, cmd);
    WriteContentBytes(data, size);
    return {};
}

MaybeError CaptureContext::CaptureQueueWriteTexture(const TexelCopyTextureInfo& destination,
                                                    const void* data,
                                                    size_t dataSize,
                                                    const TexelCopyBufferLayout& dataLayout,
                                                    const TexelExtent3D& writeSizePixel) {
    DAWN_TRY(AddResource(ToBackend(destination.texture)));
    schema::RootCommandWriteTextureCmd cmd{{
        .data = {{
            .destination = ToSchema(*this, destination),
            .layout = ToSchema(dataLayout),
            .size = ToSchema(writeSizePixel),
            .dataSize = dataSize,
        }},
    }};
    Serialize(*this, cmd);

    CaptureContext::ScopedContentWriter writer(*this);
    writer.WriteContentBytes(data, dataSize);
    return {};
}

wgpu::TextureAspect ToDawn(const Aspect aspect) {
    switch (aspect) {
        case Aspect::Depth:
            return wgpu::TextureAspect::DepthOnly;
        case Aspect::Stencil:
            return wgpu::TextureAspect::StencilOnly;
        case Aspect::Plane0:
            return wgpu::TextureAspect::Plane0Only;
        case Aspect::Plane1:
            return wgpu::TextureAspect::Plane1Only;
        case Aspect::Plane2:
            return wgpu::TextureAspect::Plane2Only;
        default:
            return wgpu::TextureAspect::All;
    }
}

schema::Origin3D ToSchema(const TexelOrigin3D& origin) {
    return {{
        .x = static_cast<uint32_t>(origin.x),
        .y = static_cast<uint32_t>(origin.y),
        .z = static_cast<uint32_t>(origin.z),
    }};
}

schema::Extent3D ToSchema(const TexelExtent3D& extent) {
    return {{
        .width = static_cast<uint32_t>(extent.width),
        .height = static_cast<uint32_t>(extent.height),
        .depthOrArrayLayers = static_cast<uint32_t>(extent.depthOrArrayLayers),
    }};
}

schema::Color ToSchema(const Color& color) {
    return {{
        .r = color.r,
        .g = color.g,
        .b = color.b,
        .a = color.a,
    }};
}

schema::TexelCopyBufferLayout ToSchema(const BufferCopy& bufferCopy,
                                       const TypedTexelBlockInfo& blockInfo) {
    return {{
        .offset = bufferCopy.offset,
        .bytesPerRow = static_cast<uint32_t>(blockInfo.ToBytes(bufferCopy.blocksPerRow)),
        .rowsPerImage = static_cast<uint32_t>(bufferCopy.rowsPerImage),
    }};
}

schema::TexelCopyBufferInfo ToSchema(CaptureContext& captureContext,
                                     const BufferCopy& bufferCopy,
                                     const TypedTexelBlockInfo& blockInfo) {
    return {{
        .bufferId = captureContext.GetId(bufferCopy.buffer),
        .layout = ToSchema(bufferCopy, blockInfo),
    }};
}

schema::TexelCopyTextureInfo ToSchema(CaptureContext& captureContext,
                                      const TextureCopy& textureCopy) {
    return {{
        .textureId = captureContext.GetId(textureCopy.texture),
        .mipLevel = textureCopy.mipLevel,
        .origin = ToSchema(textureCopy.origin),
        .aspect = ToDawn(textureCopy.aspect),
    }};
}

schema::TexelCopyBufferLayout ToSchema(const TexelCopyBufferLayout& layout) {
    return {{
        .offset = layout.offset,
        .bytesPerRow = layout.bytesPerRow,
        .rowsPerImage = layout.rowsPerImage,
    }};
}

schema::TexelCopyTextureInfo ToSchema(CaptureContext& captureContext,
                                      const TexelCopyTextureInfo& info) {
    return {{
        .textureId = captureContext.GetId(info.texture),
        .mipLevel = info.mipLevel,
        .origin = ToSchema(info.origin),
        .aspect = info.aspect,
    }};
}

schema::TimestampWrites ToSchema(CaptureContext& captureContext,
                                 const TimestampWrites& timestampWrites) {
    return {{
        .querySetId = captureContext.GetId(timestampWrites.querySet),
        .beginningOfPassWriteIndex = timestampWrites.beginningOfPassWriteIndex,
        .endOfPassWriteIndex = timestampWrites.endOfPassWriteIndex,
    }};
}

schema::ProgrammableStage ToSchema(CaptureContext& captureContext, const ProgrammableStage& stage) {
    std::vector<schema::PipelineConstant> constants;
    for (const auto& [name, value] : stage.constants) {
        constants.push_back({{
            .name = name,
            .value = value,
        }});
    }
    return {{
        .moduleId = captureContext.GetId(stage.module.Get()),
        .entryPoint = stage.entryPoint,
        .constants = constants,
    }};
}

}  // namespace dawn::native::webgpu
