// Copyright 2019 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 <array>

#include "common/Assert.h"
#include "common/BitSetIterator.h"
#include "dawn_native/Features.h"

namespace dawn::native {
    namespace {

        struct FeatureEnumAndInfo {
            Feature feature;
            FeatureInfo info;
            bool WGPUDeviceProperties::*memberInWGPUDeviceProperties;
        };

        using FeatureEnumAndInfoList =
            std::array<FeatureEnumAndInfo, static_cast<size_t>(Feature::EnumCount)>;

        static constexpr FeatureEnumAndInfoList kFeatureNameAndInfoList = {
            {{Feature::TextureCompressionBC,
              {"texture-compression-bc", "Support Block Compressed (BC) texture formats",
               "https://bugs.chromium.org/p/dawn/issues/detail?id=42"},
              &WGPUDeviceProperties::textureCompressionBC},
             {Feature::TextureCompressionETC2,
              {"texture-compression-etc2",
               "Support Ericsson Texture Compressed (ETC2/EAC) texture "
               "formats",
               "https://bugs.chromium.org/p/dawn/issues/detail?id=955"},
              &WGPUDeviceProperties::textureCompressionETC2},
             {Feature::TextureCompressionASTC,
              {"texture-compression-astc",
               "Support Adaptable Scalable Texture Compressed (ASTC) "
               "texture formats",
               "https://bugs.chromium.org/p/dawn/issues/detail?id=955"},
              &WGPUDeviceProperties::textureCompressionASTC},
             {Feature::ShaderFloat16,
              {"shader-float16",
               "Support 16bit float arithmetic and declarations in uniform and storage buffers",
               "https://bugs.chromium.org/p/dawn/issues/detail?id=426"},
              &WGPUDeviceProperties::shaderFloat16},
             {Feature::PipelineStatisticsQuery,
              {"pipeline-statistics-query", "Support Pipeline Statistics Query",
               "https://bugs.chromium.org/p/dawn/issues/detail?id=434"},
              &WGPUDeviceProperties::pipelineStatisticsQuery},
             {Feature::TimestampQuery,
              {"timestamp-query", "Support Timestamp Query",
               "https://bugs.chromium.org/p/dawn/issues/detail?id=434"},
              &WGPUDeviceProperties::timestampQuery},
             {Feature::DepthClamping,
              {"depth-clamping", "Clamp depth to [0, 1] in NDC space instead of clipping",
               "https://bugs.chromium.org/p/dawn/issues/detail?id=716"},
              &WGPUDeviceProperties::depthClamping},
             {Feature::Depth24UnormStencil8,
              {"depth24unorm-stencil8", "Support depth24unorm-stencil8 texture format",
               "https://bugs.chromium.org/p/dawn/issues/detail?id=690"},
              &WGPUDeviceProperties::depth24UnormStencil8},
             {Feature::Depth32FloatStencil8,
              {"depth32float-stencil8", "Support depth32float-stencil8 texture format",
               "https://bugs.chromium.org/p/dawn/issues/detail?id=690"},
              &WGPUDeviceProperties::depth32FloatStencil8},
             {Feature::DawnInternalUsages,
              {"dawn-internal-usages",
               "Add internal usages to resources to affect how the texture is allocated, but not "
               "frontend validation. Other internal commands may access this usage.",
               "https://dawn.googlesource.com/dawn/+/refs/heads/main/docs/dawn/features/"
               "dawn_internal_usages.md"},
              &WGPUDeviceProperties::dawnInternalUsages},
             {Feature::MultiPlanarFormats,
              {"multiplanar-formats",
               "Import and use multi-planar texture formats with per plane views",
               "https://bugs.chromium.org/p/dawn/issues/detail?id=551"},
              &WGPUDeviceProperties::multiPlanarFormats},
             {Feature::DawnNative,
              {"dawn-native", "WebGPU is running on top of dawn_native.",
               "https://dawn.googlesource.com/dawn/+/refs/heads/main/docs/dawn/features/"
               "dawn_native.md"},
              &WGPUDeviceProperties::dawnNative}}};

        Feature FromAPIFeature(wgpu::FeatureName feature) {
            switch (feature) {
                case wgpu::FeatureName::Undefined:
                    return Feature::InvalidEnum;

                case wgpu::FeatureName::TimestampQuery:
                    return Feature::TimestampQuery;
                case wgpu::FeatureName::PipelineStatisticsQuery:
                    return Feature::PipelineStatisticsQuery;
                case wgpu::FeatureName::TextureCompressionBC:
                    return Feature::TextureCompressionBC;
                case wgpu::FeatureName::TextureCompressionETC2:
                    return Feature::TextureCompressionETC2;
                case wgpu::FeatureName::TextureCompressionASTC:
                    return Feature::TextureCompressionASTC;
                case wgpu::FeatureName::DepthClamping:
                    return Feature::DepthClamping;
                case wgpu::FeatureName::Depth24UnormStencil8:
                    return Feature::Depth24UnormStencil8;
                case wgpu::FeatureName::Depth32FloatStencil8:
                    return Feature::Depth32FloatStencil8;
                case wgpu::FeatureName::DawnShaderFloat16:
                    return Feature::ShaderFloat16;
                case wgpu::FeatureName::DawnInternalUsages:
                    return Feature::DawnInternalUsages;
                case wgpu::FeatureName::DawnMultiPlanarFormats:
                    return Feature::MultiPlanarFormats;
                case wgpu::FeatureName::DawnNative:
                    return Feature::DawnNative;

                case wgpu::FeatureName::IndirectFirstInstance:
                    return Feature::InvalidEnum;
            }
            return Feature::InvalidEnum;
        }

        wgpu::FeatureName ToAPIFeature(Feature feature) {
            switch (feature) {
                case Feature::TextureCompressionBC:
                    return wgpu::FeatureName::TextureCompressionBC;
                case Feature::TextureCompressionETC2:
                    return wgpu::FeatureName::TextureCompressionETC2;
                case Feature::TextureCompressionASTC:
                    return wgpu::FeatureName::TextureCompressionASTC;
                case Feature::PipelineStatisticsQuery:
                    return wgpu::FeatureName::PipelineStatisticsQuery;
                case Feature::TimestampQuery:
                    return wgpu::FeatureName::TimestampQuery;
                case Feature::DepthClamping:
                    return wgpu::FeatureName::DepthClamping;
                case Feature::Depth24UnormStencil8:
                    return wgpu::FeatureName::Depth24UnormStencil8;
                case Feature::Depth32FloatStencil8:
                    return wgpu::FeatureName::Depth32FloatStencil8;
                case Feature::ShaderFloat16:
                    return wgpu::FeatureName::DawnShaderFloat16;
                case Feature::DawnInternalUsages:
                    return wgpu::FeatureName::DawnInternalUsages;
                case Feature::MultiPlanarFormats:
                    return wgpu::FeatureName::DawnMultiPlanarFormats;
                case Feature::DawnNative:
                    return wgpu::FeatureName::DawnNative;

                case Feature::EnumCount:
                    UNREACHABLE();
            }
        }

    }  // anonymous namespace

    void FeaturesSet::EnableFeature(Feature feature) {
        ASSERT(feature != Feature::InvalidEnum);
        const size_t featureIndex = static_cast<size_t>(feature);
        featuresBitSet.set(featureIndex);
    }

    void FeaturesSet::EnableFeature(wgpu::FeatureName feature) {
        EnableFeature(FromAPIFeature(feature));
    }

    bool FeaturesSet::IsEnabled(Feature feature) const {
        ASSERT(feature != Feature::InvalidEnum);
        const size_t featureIndex = static_cast<size_t>(feature);
        return featuresBitSet[featureIndex];
    }

    bool FeaturesSet::IsEnabled(wgpu::FeatureName feature) const {
        Feature f = FromAPIFeature(feature);
        return f != Feature::InvalidEnum && IsEnabled(f);
    }

    size_t FeaturesSet::EnumerateFeatures(wgpu::FeatureName* features) const {
        for (uint32_t i : IterateBitSet(featuresBitSet)) {
            wgpu::FeatureName feature = ToAPIFeature(static_cast<Feature>(i));
            if (features != nullptr) {
                *features = feature;
                features += 1;
            }
        }
        return featuresBitSet.count();
    }

    std::vector<const char*> FeaturesSet::GetEnabledFeatureNames() const {
        std::vector<const char*> enabledFeatureNames(featuresBitSet.count());

        uint32_t index = 0;
        for (uint32_t i : IterateBitSet(featuresBitSet)) {
            Feature feature = static_cast<Feature>(i);
            ASSERT(feature != Feature::InvalidEnum);

            const FeatureEnumAndInfo& featureNameAndInfo = kFeatureNameAndInfoList[i];
            ASSERT(featureNameAndInfo.feature == feature);

            enabledFeatureNames[index] = featureNameAndInfo.info.name;
            ++index;
        }
        return enabledFeatureNames;
    }

    void FeaturesSet::InitializeDeviceProperties(WGPUDeviceProperties* properties) const {
        ASSERT(properties != nullptr);

        for (uint32_t i : IterateBitSet(featuresBitSet)) {
            properties->*(kFeatureNameAndInfoList[i].memberInWGPUDeviceProperties) = true;
        }
    }

    wgpu::FeatureName FeatureEnumToAPIFeature(Feature feature) {
        ASSERT(feature != Feature::InvalidEnum);
        return ToAPIFeature(feature);
    }

    FeaturesInfo::FeaturesInfo() {
        for (size_t index = 0; index < kFeatureNameAndInfoList.size(); ++index) {
            const FeatureEnumAndInfo& featureNameAndInfo = kFeatureNameAndInfoList[index];
            ASSERT(index == static_cast<size_t>(featureNameAndInfo.feature));
            mFeatureNameToEnumMap[featureNameAndInfo.info.name] = featureNameAndInfo.feature;
        }
    }

    const FeatureInfo* FeaturesInfo::GetFeatureInfo(wgpu::FeatureName feature) const {
        Feature f = FromAPIFeature(feature);
        if (f == Feature::InvalidEnum) {
            return nullptr;
        }
        return &kFeatureNameAndInfoList[static_cast<size_t>(f)].info;
    }

    Feature FeaturesInfo::FeatureNameToEnum(const char* featureName) const {
        ASSERT(featureName);

        const auto& iter = mFeatureNameToEnumMap.find(featureName);
        if (iter != mFeatureNameToEnumMap.cend()) {
            return kFeatureNameAndInfoList[static_cast<size_t>(iter->second)].feature;
        }

        // TODO(dawn:550): Remove this fallback logic when Chromium is updated.
        constexpr std::array<std::pair<const char*, const char*>, 6>
            kReplacementsForDeprecatedNames = {{
                {"texture_compression_bc", "texture-compression-bc"},
                {"depth_clamping", "depth-clamping"},
                {"pipeline_statistics_query", "pipeline-statistics-query"},
                {"shader_float16", "shader-float16"},
                {"timestamp_query", "timestamp-query"},
                {"multiplanar_formats", "multiplanar-formats"},
            }};
        for (const auto& [name, replacement] : kReplacementsForDeprecatedNames) {
            if (strcmp(featureName, name) == 0) {
                return FeatureNameToEnum(replacement);
            }
        }

        return Feature::InvalidEnum;
    }

    wgpu::FeatureName FeaturesInfo::FeatureNameToAPIEnum(const char* featureName) const {
        Feature f = FeatureNameToEnum(featureName);
        if (f != Feature::InvalidEnum) {
            return ToAPIFeature(f);
        }
        // Pass something invalid.
        return static_cast<wgpu::FeatureName>(-1);
    }

}  // namespace dawn::native
