// Copyright 2024 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/wire/client/Surface.h"

#include <algorithm>
#include <utility>

#include "dawn/wire/client/webgpu.h"
#include "src/dawn/wire/client/Client.h"
#include "src/dawn/wire/client/Device.h"
#include "src/dawn/wire/client/Texture.h"
#include "src/utils/compiler.h"
#include "src/utils/log.h"
#include "src/utils/platform.h"

namespace dawn::wire::client {

Surface::Surface(const ObjectBaseParams& params, const WGPUSurfaceCapabilities* capabilities)
    : ObjectBase(params) {
    // Copy over the capabilities.
    mSupportedUsages = capabilities->usages;
    mSupportedFormats.assign(capabilities->formats,
                             DAWN_UNSAFE_TODO(capabilities->formats + capabilities->formatCount));
    mSupportedPresentModes.assign(
        capabilities->presentModes,
        DAWN_UNSAFE_TODO(capabilities->presentModes + capabilities->presentModeCount));
    mSupportedAlphaModes.assign(
        capabilities->alphaModes,
        DAWN_UNSAFE_TODO(capabilities->alphaModes + capabilities->alphaModeCount));

    DAWN_ASSERT(!mSupportedFormats.empty() && !mSupportedPresentModes.empty() &&
                !mSupportedAlphaModes.empty());
}

Surface::~Surface() = default;

ObjectType Surface::GetObjectType() const {
    return ObjectType::Surface;
}

void Surface::APIConfigure(const WGPUSurfaceConfiguration* config) {
    mConfiguredDevice = FromAPI(config->device);

    mTextureDescriptor = {};
    mTextureDescriptor.size = {config->width, config->height, 1};
    mTextureDescriptor.format = config->format;
    mTextureDescriptor.usage = config->usage;
    mTextureDescriptor.dimension = WGPUTextureDimension_2D;
    mTextureDescriptor.mipLevelCount = 1;
    mTextureDescriptor.sampleCount = 1;

    SurfaceConfigureCmd cmd;
    cmd.self = ToAPI(this);
    cmd.config = config;
    GetClient()->SerializeCommand(cmd);
}

WGPUStatus Surface::APIPresent() {
    if (mConfiguredDevice == nullptr) {
        dawn::ErrorLog() << "Surface::Present on an unconfigured Surface.";
        return WGPUStatus_Error;
    }

    SurfacePresentCmd cmd;
    cmd.self = ToAPI(this);
    GetClient()->SerializeCommand(cmd);

    // The only synchronous error is if the surface isn't configured.
    // Otherwise, we let the server report errors via the device.
    return WGPUStatus_Success;
}

void Surface::APIUnconfigure() {
    mConfiguredDevice = nullptr;

    SurfaceUnconfigureCmd cmd;
    cmd.self = ToAPI(this);
    GetClient()->SerializeCommand(cmd);
}

WGPUTextureFormat Surface::APIGetPreferredFormat([[maybe_unused]] WGPUAdapter adapter) const {
    dawn::ErrorLog() << "Surface::GetPreferredFormat is deprecated, use "
                        "Surface::GetCapabilities().formats[0] instead.";
    return mSupportedFormats[0];
}

WGPUStatus Surface::APIGetCapabilities(WGPUAdapter adapter,
                                       WGPUSurfaceCapabilities* capabilities) const {
    // Return the capabilities that were provided when injecting the surface.
    capabilities->nextInChain = nullptr;
    capabilities->usages = mSupportedUsages;

    capabilities->presentModeCount = mSupportedPresentModes.size();
    WGPUPresentMode* presentModes = new WGPUPresentMode[capabilities->presentModeCount];
    std::copy(mSupportedPresentModes.begin(), mSupportedPresentModes.end(), presentModes);
    capabilities->presentModes = presentModes;

    capabilities->formatCount = mSupportedFormats.size();
    WGPUTextureFormat* formats = new WGPUTextureFormat[capabilities->formatCount];
    std::copy(mSupportedFormats.begin(), mSupportedFormats.end(), formats);
    capabilities->formats = formats;

    capabilities->alphaModeCount = mSupportedAlphaModes.size();
    WGPUCompositeAlphaMode* alphaModes = new WGPUCompositeAlphaMode[capabilities->alphaModeCount];
    std::copy(mSupportedAlphaModes.begin(), mSupportedAlphaModes.end(), alphaModes);
    capabilities->alphaModes = alphaModes;

    return WGPUStatus_Success;
}

void Surface::APIGetCurrentTexture(WGPUSurfaceTexture* surfaceTexture) {
    // Handle error cases that return no textures first.
    surfaceTexture->texture = nullptr;

    surfaceTexture->status = WGPUSurfaceGetCurrentTextureStatus_Error;
    if (mConfiguredDevice == nullptr) {
        return;
    }

    // Assume texture creation will work in the server and return a new texture proxy.
    Client* wireClient = GetClient();
    Ref<Texture> texture = wireClient->Make<Texture>(mConfiguredDevice.Get(), &mTextureDescriptor);

    SurfaceGetCurrentTextureCmd cmd;
    cmd.surfaceId = GetWireHandle(wireClient).id;
    cmd.textureHandle = texture->GetWireHandle(wireClient);
    cmd.configuredDeviceId = mConfiguredDevice->GetWireHandle(wireClient).id;
    wireClient->SerializeCommand(cmd);

    surfaceTexture->status = WGPUSurfaceGetCurrentTextureStatus_SuccessOptimal;
    surfaceTexture->texture = ReturnToAPI(std::move(texture));
}

void APIFreeMembers(WGPUSurfaceCapabilities capabilities) {
    delete[] capabilities.presentModes;
    delete[] capabilities.formats;
    delete[] capabilities.alphaModes;
}

}  // namespace dawn::wire::client
