// 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 <utility>
#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(std::vector<wgpu::FeatureName> features) {
        for (wgpu::FeatureName feature : features) {
            switch (feature) {
                case wgpu::FeatureName::Depth32FloatStencil8:
                    enabled_.emplace(interop::GPUFeatureName::kDepth32FloatStencil8);
                    break;
                case wgpu::FeatureName::TimestampQuery:
                    enabled_.emplace(interop::GPUFeatureName::kTimestampQuery);
                    break;
                case wgpu::FeatureName::TextureCompressionBC:
                    enabled_.emplace(interop::GPUFeatureName::kTextureCompressionBc);
                    break;
                case wgpu::FeatureName::TextureCompressionETC2:
                    enabled_.emplace(interop::GPUFeatureName::kTextureCompressionEtc2);
                    break;
                case wgpu::FeatureName::TextureCompressionASTC:
                    enabled_.emplace(interop::GPUFeatureName::kTextureCompressionAstc);
                    break;
                case wgpu::FeatureName::IndirectFirstInstance:
                    enabled_.emplace(interop::GPUFeatureName::kIndirectFirstInstance);
                    break;
                case wgpu::FeatureName::DepthClipControl:
                    enabled_.emplace(interop::GPUFeatureName::kDepthClipControl);
                    break;
                default:
                    break;
            }
        }
        // TODO(dawn:1123) add support for these extensions when possible.
        // wgpu::interop::GPUFeatureName::kShaderF16
        // wgpu::interop::GPUFeatureName::kBgra8UnormStorage
    }

    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) {}

// TODO(dawn:1133): Avoid the extra copy by making the generator make a virtual method with const
// std::string&
interop::Interface<interop::GPUSupportedFeatures> GPUAdapter::getFeatures(Napi::Env env) {
    wgpu::Adapter adapter(adapter_.Get());
    size_t count = adapter.EnumerateFeatures(nullptr);
    std::vector<wgpu::FeatureName> features(count);
    adapter.EnumerateFeatures(&features[0]);
    return interop::GPUSupportedFeatures::Create<Features>(env, std::move(features));
}

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::kDepth32FloatStencil8:
                requiredFeatures.emplace_back(wgpu::FeatureName::Depth32FloatStencil8);
                continue;
            case interop::GPUFeatureName::kDepthClipControl:
            case interop::GPUFeatureName::kShaderF16:
            case interop::GPUFeatureName::kIndirectFirstInstance:
            case interop::GPUFeatureName::kBgra8UnormStorage:
                // 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;
}

interop::Promise<interop::Interface<interop::GPUAdapterInfo>> GPUAdapter::requestAdapterInfo(
    Napi::Env,
    std::vector<std::string> unmaskHints) {
    UNIMPLEMENTED();
}

}  // namespace wgpu::binding
