// Copyright 2026 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.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "dawn/native/webgpu/SwapChainWGPU.h"

#include <utility>
#include <vector>

#include "dawn/common/StringViewUtils.h"
#include "dawn/native/Adapter.h"
#include "dawn/native/ChainUtils.h"
#include "dawn/native/Surface.h"
#include "dawn/native/webgpu/CaptureContext.h"
#include "dawn/native/webgpu/DeviceWGPU.h"
#include "dawn/native/webgpu/QueueWGPU.h"
#include "dawn/native/webgpu/TextureWGPU.h"
#include "dawn/native/webgpu/ToWGPU.h"
#include "dawn/native/webgpu/WebGPUError.h"

namespace dawn::native::webgpu {

ResultOrError<WGPUSurface> CreateWGPUSurface(const DawnProcTable& procs,
                                             WGPUInstance instance,
                                             const Surface* surface) {
    WGPUSurfaceDescriptor descriptor = WGPU_SURFACE_DESCRIPTOR_INIT;
    descriptor.label = ToOutputStringView(surface->GetLabel());

    // Reconstruct the chained descriptor based on the surface type.
    WGPUSurfaceSourceAndroidNativeWindow androidDesc =
        WGPU_SURFACE_SOURCE_ANDROID_NATIVE_WINDOW_INIT;
    WGPUSurfaceSourceMetalLayer metalDesc = WGPU_SURFACE_SOURCE_METAL_LAYER_INIT;
    WGPUSurfaceSourceWindowsHWND hwndDesc = WGPU_SURFACE_SOURCE_WINDOWS_HWND_INIT;
    WGPUSurfaceSourceWaylandSurface waylandDesc = WGPU_SURFACE_SOURCE_WAYLAND_SURFACE_INIT;
    WGPUSurfaceSourceXlibWindow xlibDesc = WGPU_SURFACE_SOURCE_XLIB_WINDOW_INIT;
    WGPUSurfaceDescriptorFromWindowsCoreWindow coreWindowDesc =
        WGPU_SURFACE_DESCRIPTOR_FROM_WINDOWS_CORE_WINDOW_INIT;
    WGPUSurfaceDescriptorFromWindowsUWPSwapChainPanel uwpDesc =
        WGPU_SURFACE_DESCRIPTOR_FROM_WINDOWS_UWP_SWAP_CHAIN_PANEL_INIT;
    WGPUSurfaceDescriptorFromWindowsWinUISwapChainPanel winuiDesc =
        WGPU_SURFACE_DESCRIPTOR_FROM_WINDOWS_WINUI_SWAP_CHAIN_PANEL_INIT;

    switch (surface->GetType()) {
        case Surface::Type::AndroidWindow:
            androidDesc.chain.sType = WGPUSType_SurfaceSourceAndroidNativeWindow;
            androidDesc.window = surface->GetAndroidNativeWindow();
            descriptor.nextInChain = &androidDesc.chain;
            break;
        case Surface::Type::MetalLayer:
            metalDesc.chain.sType = WGPUSType_SurfaceSourceMetalLayer;
            metalDesc.layer = surface->GetMetalLayer();
            descriptor.nextInChain = &metalDesc.chain;
            break;
        case Surface::Type::WindowsHWND:
            hwndDesc.chain.sType = WGPUSType_SurfaceSourceWindowsHWND;
            hwndDesc.hinstance = surface->GetHInstance();
            hwndDesc.hwnd = surface->GetHWND();
            descriptor.nextInChain = &hwndDesc.chain;
            break;
        case Surface::Type::WindowsCoreWindow:
            coreWindowDesc.chain.sType = WGPUSType_SurfaceDescriptorFromWindowsCoreWindow;
            coreWindowDesc.coreWindow = surface->GetCoreWindow();
            descriptor.nextInChain = &coreWindowDesc.chain;
            break;
        case Surface::Type::WindowsUWPSwapChainPanel:
            uwpDesc.chain.sType = WGPUSType_SurfaceDescriptorFromWindowsUWPSwapChainPanel;
            uwpDesc.swapChainPanel = surface->GetUWPSwapChainPanel();
            descriptor.nextInChain = &uwpDesc.chain;
            break;
        case Surface::Type::WindowsWinUISwapChainPanel:
            winuiDesc.chain.sType = WGPUSType_SurfaceDescriptorFromWindowsWinUISwapChainPanel;
            winuiDesc.swapChainPanel = surface->GetWinUISwapChainPanel();
            descriptor.nextInChain = &winuiDesc.chain;
            break;
        case Surface::Type::WaylandSurface:
            waylandDesc.chain.sType = WGPUSType_SurfaceSourceWaylandSurface;
            waylandDesc.display = surface->GetWaylandDisplay();
            waylandDesc.surface = surface->GetWaylandSurface();
            descriptor.nextInChain = &waylandDesc.chain;
            break;
        case Surface::Type::XlibWindow:
            xlibDesc.chain.sType = WGPUSType_SurfaceSourceXlibWindow;
            xlibDesc.display = surface->GetXDisplay();
            xlibDesc.window = surface->GetXWindow();
            descriptor.nextInChain = &xlibDesc.chain;
            break;
        default:
            return DAWN_VALIDATION_ERROR("Unknown surface type %s.", surface->GetType());
    }

    WGPUSurface innerSurface = procs.instanceCreateSurface(instance, &descriptor);
    DAWN_ASSERT(innerSurface);
    return innerSurface;
}

// static
ResultOrError<Ref<SwapChain>> SwapChain::Create(Device* device,
                                                Surface* surface,
                                                SwapChainBase* previousSwapChain,
                                                const SurfaceConfiguration* config) {
    WGPUSurface innerSurface = nullptr;

    if (previousSwapChain != nullptr) {
        // Transfer the inner surface ownership.
        SwapChain* backendSwapChain = ToBackend(previousSwapChain);
        innerSurface = backendSwapChain->mInnerHandle;
        backendSwapChain->mInnerHandle = nullptr;
    } else {
        DAWN_TRY_ASSIGN(innerSurface,
                        CreateWGPUSurface(*device->wgpu, device->GetInnerInstance(), surface));
    }
    DAWN_ASSERT(innerSurface);

    WGPUSurfaceConfiguration innerConfig = {};
    innerConfig.device = device->GetInnerHandle();
    innerConfig.format = ToAPI(config->format);
    innerConfig.usage = ToAPI(config->usage);
    innerConfig.viewFormatCount = config->viewFormatCount;
    std::vector<WGPUTextureFormat> viewFormats;
    for (uint32_t i = 0; i < config->viewFormatCount; ++i) {
        viewFormats.push_back(ToAPI(config->viewFormats[i]));
    }
    innerConfig.viewFormats = viewFormats.data();
    innerConfig.alphaMode = ToAPI(config->alphaMode);
    innerConfig.width = config->width;
    innerConfig.height = config->height;
    innerConfig.presentMode = ToAPI(config->presentMode);

    device->wgpu->surfaceConfigure(innerSurface, &innerConfig);

    if (ToBackend(device->GetQueue())->IsCapturing()) {
        CaptureContext* context = ToBackend(device->GetQueue())->GetCaptureContext();
        context->CaptureSurfaceConfigure(surface, config);
    }

    return AcquireRef(new SwapChain(device, surface, config, innerSurface));
}

SwapChain::SwapChain(Device* device,
                     Surface* surface,
                     const SurfaceConfiguration* config,
                     WGPUSurface innerSurface)
    : SwapChainBase(device, surface, config), ObjectWGPU(device->wgpu->surfaceRelease) {
    mInnerHandle = innerSurface;
}

SwapChain::~SwapChain() = default;

WGPUSurface SwapChain::GetInnerSurface() const {
    DAWN_ASSERT(mInnerHandle);
    return mInnerHandle;
}

ResultOrError<SwapChainTextureInfo> SwapChain::GetCurrentTextureImpl() {
    Device* device = ToBackend(GetDevice());
    WGPUSurfaceTexture innerSurfaceTexture = WGPU_SURFACE_TEXTURE_INIT;
    device->wgpu->surfaceGetCurrentTexture(mInnerHandle, &innerSurfaceTexture);

    SwapChainTextureInfo info;
    info.status = FromAPI(innerSurfaceTexture.status);

    if (info.status != wgpu::SurfaceGetCurrentTextureStatus::SuccessOptimal &&
        info.status != wgpu::SurfaceGetCurrentTextureStatus::SuccessSuboptimal) {
        DAWN_ASSERT(innerSurfaceTexture.texture == nullptr);
        return info;
    }

    TextureDescriptor desc = GetSwapChainBaseTextureDescriptor(this);

    // Note: We're creating a Texture wrapper around the inner handle.
    Ref<Texture> texture;
    UnpackedPtr<TextureDescriptor> unpacked = Unpack(&desc);
    texture = Texture::CreateFromSurfaceTexture(device, unpacked, innerSurfaceTexture);

    if (ToBackend(device->GetQueue())->IsCapturing()) {
        CaptureContext* context = ToBackend(device->GetQueue())->GetCaptureContext();
        DAWN_TRY(context->CaptureSurfaceGetCurrentTexture(GetSurface(), texture.Get()));
    }

    mCurrentTexture = texture;
    info.texture = std::move(texture);

    return info;
}

MaybeError SwapChain::PresentImpl() {
    Device* device = ToBackend(GetDevice());

    WGPUStatus status = device->wgpu->surfacePresent(mInnerHandle);

    DAWN_TRY(CheckWGPUSuccess(status, "surfacePresent"));

    if (ToBackend(device->GetQueue())->IsCapturing()) {
        CaptureContext* context = ToBackend(device->GetQueue())->GetCaptureContext();
        context->CaptureSurfacePresent(GetSurface());
    }

    DAWN_ASSERT(mCurrentTexture != nullptr);
    mCurrentTexture->Destroy();
    mCurrentTexture = nullptr;

    return {};
}

void SwapChain::DetachFromSurfaceImpl() {
    if (mCurrentTexture != nullptr) {
        mCurrentTexture->Destroy();
        mCurrentTexture = nullptr;
    }
}

}  // namespace dawn::native::webgpu
