// Copyright 2021 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "src/dawn/node/binding/GPUAdapter.h"

#include <unordered_set>
#include <vector>

#include "src/dawn/node/binding/Errors.h"
#include "src/dawn/node/binding/Flags.h"
#include "src/dawn/node/binding/GPUDevice.h"
#include "src/dawn/node/binding/GPUSupportedLimits.h"

namespace {
// TODO(amaiorano): Move to utility header
std::vector<std::string> Split(const std::string& s, char delim) {
    if (s.empty()) {
        return {};
    }

    std::vector<std::string> result;
    const size_t lastIndex = s.length() - 1;
    size_t startIndex = 0;
    size_t i = startIndex;

    while (i <= lastIndex) {
        if (s[i] == delim) {
            auto token = s.substr(startIndex, i - startIndex);
            if (!token.empty()) {  // Discard empty tokens
                result.push_back(token);
            }
            startIndex = i + 1;
        } else if (i == lastIndex) {
            auto token = s.substr(startIndex, i - startIndex + 1);
            if (!token.empty()) {  // Discard empty tokens
                result.push_back(token);
            }
        }
        ++i;
    }
    return result;
}
}  // namespace

#define FOR_EACH_LIMIT(X)                        \
    X(maxTextureDimension1D)                     \
    X(maxTextureDimension2D)                     \
    X(maxTextureDimension3D)                     \
    X(maxTextureArrayLayers)                     \
    X(maxBindGroups)                             \
    X(maxDynamicUniformBuffersPerPipelineLayout) \
    X(maxDynamicStorageBuffersPerPipelineLayout) \
    X(maxSampledTexturesPerShaderStage)          \
    X(maxSamplersPerShaderStage)                 \
    X(maxStorageBuffersPerShaderStage)           \
    X(maxStorageTexturesPerShaderStage)          \
    X(maxUniformBuffersPerShaderStage)           \
    X(maxUniformBufferBindingSize)               \
    X(maxStorageBufferBindingSize)               \
    X(minUniformBufferOffsetAlignment)           \
    X(minStorageBufferOffsetAlignment)           \
    X(maxVertexBuffers)                          \
    X(maxVertexAttributes)                       \
    X(maxVertexBufferArrayStride)                \
    X(maxInterStageShaderComponents)             \
    X(maxComputeWorkgroupStorageSize)            \
    X(maxComputeInvocationsPerWorkgroup)         \
    X(maxComputeWorkgroupSizeX)                  \
    X(maxComputeWorkgroupSizeY)                  \
    X(maxComputeWorkgroupSizeZ)                  \
    X(maxComputeWorkgroupsPerDimension)

namespace wgpu::binding {

namespace {

////////////////////////////////////////////////////////////////////////////////
// wgpu::binding::<anon>::Features
// Implements interop::GPUSupportedFeatures
////////////////////////////////////////////////////////////////////////////////
class Features : public interop::GPUSupportedFeatures {
  public:
    explicit Features(WGPUDeviceProperties properties) {
        if (properties.depth24UnormStencil8) {
            enabled_.emplace(interop::GPUFeatureName::kDepth24UnormStencil8);
        }
        if (properties.depth32FloatStencil8) {
            enabled_.emplace(interop::GPUFeatureName::kDepth32FloatStencil8);
        }
        if (properties.timestampQuery) {
            enabled_.emplace(interop::GPUFeatureName::kTimestampQuery);
        }
        if (properties.textureCompressionBC) {
            enabled_.emplace(interop::GPUFeatureName::kTextureCompressionBc);
        }
        if (properties.textureCompressionETC2) {
            enabled_.emplace(interop::GPUFeatureName::kTextureCompressionEtc2);
        }
        if (properties.textureCompressionASTC) {
            enabled_.emplace(interop::GPUFeatureName::kTextureCompressionAstc);
        }
        if (properties.timestampQuery) {
            enabled_.emplace(interop::GPUFeatureName::kTimestampQuery);
        }

        // TODO(dawn:1123) add support for these extensions when possible.
        // wgpu::interop::GPUFeatureName::kIndirectFirstInstance
        // wgpu::interop::GPUFeatureName::kDepthClipControl
    }

    bool has(interop::GPUFeatureName feature) { return enabled_.count(feature) != 0; }

    // interop::GPUSupportedFeatures compliance
    bool has(Napi::Env, std::string name) override {
        interop::GPUFeatureName feature;
        if (interop::Converter<interop::GPUFeatureName>::FromString(name, feature)) {
            return has(feature);
        }
        return false;
    }
    std::vector<std::string> keys(Napi::Env) override {
        std::vector<std::string> out;
        out.reserve(enabled_.size());
        for (auto feature : enabled_) {
            out.push_back(interop::Converter<interop::GPUFeatureName>::ToString(feature));
        }
        return out;
    }

  private:
    std::unordered_set<interop::GPUFeatureName> enabled_;
};

}  // namespace

////////////////////////////////////////////////////////////////////////////////
// wgpu::bindings::GPUAdapter
// TODO(crbug.com/dawn/1133): This is a stub implementation. Properly implement.
////////////////////////////////////////////////////////////////////////////////
GPUAdapter::GPUAdapter(dawn::native::Adapter a, const Flags& flags) : adapter_(a), flags_(flags) {
    wgpu::AdapterProperties props;
    adapter_.GetProperties(&props);
    name_ = props.name;
}

// TODO(dawn:1133): Avoid the extra copy by making the generator make a virtual method with const
// std::string&
std::string GPUAdapter::getName(Napi::Env) {
    return name_;
}

interop::Interface<interop::GPUSupportedFeatures> GPUAdapter::getFeatures(Napi::Env env) {
    return interop::GPUSupportedFeatures::Create<Features>(env, adapter_.GetAdapterProperties());
}

interop::Interface<interop::GPUSupportedLimits> GPUAdapter::getLimits(Napi::Env env) {
    WGPUSupportedLimits limits{};
    if (!adapter_.GetLimits(&limits)) {
        Napi::Error::New(env, "failed to get adapter limits").ThrowAsJavaScriptException();
    }

    wgpu::SupportedLimits wgpuLimits{};

#define COPY_LIMIT(LIMIT) wgpuLimits.limits.LIMIT = limits.limits.LIMIT;
    FOR_EACH_LIMIT(COPY_LIMIT)
#undef COPY_LIMIT

    return interop::GPUSupportedLimits::Create<GPUSupportedLimits>(env, wgpuLimits);
}

bool GPUAdapter::getIsFallbackAdapter(Napi::Env) {
    UNIMPLEMENTED();
}

interop::Promise<interop::Interface<interop::GPUDevice>> GPUAdapter::requestDevice(
    Napi::Env env,
    interop::GPUDeviceDescriptor descriptor) {
    wgpu::DeviceDescriptor desc{};  // TODO(crbug.com/dawn/1133): Fill in.
    interop::Promise<interop::Interface<interop::GPUDevice>> promise(env, PROMISE_INFO);

    std::vector<wgpu::FeatureName> requiredFeatures;
    // See src/dawn/native/Features.cpp for enum <-> string mappings.
    for (auto required : descriptor.requiredFeatures) {
        switch (required) {
            case interop::GPUFeatureName::kTextureCompressionBc:
                requiredFeatures.emplace_back(wgpu::FeatureName::TextureCompressionBC);
                continue;
            case interop::GPUFeatureName::kTextureCompressionEtc2:
                requiredFeatures.emplace_back(wgpu::FeatureName::TextureCompressionETC2);
                continue;
            case interop::GPUFeatureName::kTextureCompressionAstc:
                requiredFeatures.emplace_back(wgpu::FeatureName::TextureCompressionASTC);
                continue;
            case interop::GPUFeatureName::kTimestampQuery:
                requiredFeatures.emplace_back(wgpu::FeatureName::TimestampQuery);
                continue;
            case interop::GPUFeatureName::kDepth24UnormStencil8:
                requiredFeatures.emplace_back(wgpu::FeatureName::Depth24UnormStencil8);
                continue;
            case interop::GPUFeatureName::kDepth32FloatStencil8:
                requiredFeatures.emplace_back(wgpu::FeatureName::Depth32FloatStencil8);
                continue;
            case interop::GPUFeatureName::kDepthClipControl:
            case interop::GPUFeatureName::kIndirectFirstInstance:
            case interop::GPUFeatureName::kShaderF16:
                // TODO(dawn:1123) Add support for these extensions when possible.
                continue;
        }
        UNIMPLEMENTED("required: ", required);
    }

    wgpu::RequiredLimits limits;
#define COPY_LIMIT(LIMIT)                                        \
    if (descriptor.requiredLimits.count(#LIMIT)) {               \
        limits.limits.LIMIT = descriptor.requiredLimits[#LIMIT]; \
        descriptor.requiredLimits.erase(#LIMIT);                 \
    }
    FOR_EACH_LIMIT(COPY_LIMIT)
#undef COPY_LIMIT

    for (auto [key, _] : descriptor.requiredLimits) {
        promise.Reject(binding::Errors::OperationError(env, "Unknown limit \"" + key + "\""));
        return promise;
    }

    // Propogate enabled/disabled dawn features
    // Note: DawnDeviceTogglesDescriptor::forceEnabledToggles and forceDisabledToggles are
    // vectors of 'const char*', so we make sure the parsed strings survive the CreateDevice()
    // call by storing them on the stack.
    std::vector<std::string> enabledToggles;
    std::vector<std::string> disabledToggles;
    std::vector<const char*> forceEnabledToggles;
    std::vector<const char*> forceDisabledToggles;
    if (auto values = flags_.Get("enable-dawn-features")) {
        enabledToggles = Split(*values, ',');
        for (auto& t : enabledToggles) {
            forceEnabledToggles.emplace_back(t.c_str());
        }
    }
    if (auto values = flags_.Get("disable-dawn-features")) {
        disabledToggles = Split(*values, ',');
        for (auto& t : disabledToggles) {
            forceDisabledToggles.emplace_back(t.c_str());
        }
    }

    desc.requiredFeaturesCount = requiredFeatures.size();
    desc.requiredFeatures = requiredFeatures.data();
    desc.requiredLimits = &limits;

    DawnTogglesDeviceDescriptor togglesDesc = {};
    desc.nextInChain = &togglesDesc;
    togglesDesc.forceEnabledTogglesCount = forceEnabledToggles.size();
    togglesDesc.forceEnabledToggles = forceEnabledToggles.data();
    togglesDesc.forceDisabledTogglesCount = forceDisabledToggles.size();
    togglesDesc.forceDisabledToggles = forceDisabledToggles.data();

    auto wgpu_device = adapter_.CreateDevice(&desc);
    if (wgpu_device) {
        promise.Resolve(interop::GPUDevice::Create<GPUDevice>(env, env, wgpu_device));
    } else {
        promise.Reject(binding::Errors::OperationError(env, "failed to create device"));
    }
    return promise;
}
}  // namespace wgpu::binding
