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

#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/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);

    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);

    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"));

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

    return {};
}

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

}  // namespace dawn::native::webgpu
