// 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 "dawn/native/webgpu_absl_format.h"

#include "dawn/native/BindingInfo.h"
#include "dawn/native/Device.h"
#include "dawn/native/Format.h"
#include "dawn/native/ObjectBase.h"
#include "dawn/native/PerStage.h"
#include "dawn/native/ShaderModule.h"
#include "dawn/native/Subresource.h"
#include "dawn/native/Surface.h"
#include "dawn/native/Texture.h"
#include "dawn/native/VertexFormat.h"

namespace dawn::native {

    //
    // Structs
    //

    absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
        const Color* value,
        const absl::FormatConversionSpec& spec,
        absl::FormatSink* s) {
        if (value == nullptr) {
            s->Append("[null]");
            return {true};
        }
        s->Append(absl::StrFormat("[Color r:%f, g:%f, b:%f, a:%f]", value->r, value->g, value->b,
                                  value->a));
        return {true};
    }

    absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
        const Extent3D* value,
        const absl::FormatConversionSpec& spec,
        absl::FormatSink* s) {
        if (value == nullptr) {
            s->Append("[null]");
            return {true};
        }
        s->Append(absl::StrFormat("[Extent3D width:%u, height:%u, depthOrArrayLayers:%u]",
                                  value->width, value->height, value->depthOrArrayLayers));
        return {true};
    }

    absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
        const Origin3D* value,
        const absl::FormatConversionSpec& spec,
        absl::FormatSink* s) {
        if (value == nullptr) {
            s->Append("[null]");
            return {true};
        }
        s->Append(absl::StrFormat("[Origin3D x:%u, y:%u, z:%u]", value->x, value->y, value->z));
        return {true};
    }

    absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
        const BindingInfo& value,
        const absl::FormatConversionSpec& spec,
        absl::FormatSink* s) {
        static const auto* const fmt =
            new absl::ParsedFormat<'u', 's', 's', 's'>("{ binding: %u, visibility: %s, %s: %s }");
        switch (value.bindingType) {
            case BindingInfoType::Buffer:
                s->Append(absl::StrFormat(*fmt, static_cast<uint32_t>(value.binding),
                                          value.visibility, value.bindingType, value.buffer));
                break;
            case BindingInfoType::Sampler:
                s->Append(absl::StrFormat(*fmt, static_cast<uint32_t>(value.binding),
                                          value.visibility, value.bindingType, value.sampler));
                break;
            case BindingInfoType::Texture:
                s->Append(absl::StrFormat(*fmt, static_cast<uint32_t>(value.binding),
                                          value.visibility, value.bindingType, value.texture));
                break;
            case BindingInfoType::StorageTexture:
                s->Append(absl::StrFormat(*fmt, static_cast<uint32_t>(value.binding),
                                          value.visibility, value.bindingType,
                                          value.storageTexture));
                break;
            case BindingInfoType::ExternalTexture:
                break;
        }
        return {true};
    }

    //
    // Objects
    //

    absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
        const DeviceBase* value,
        const absl::FormatConversionSpec& spec,
        absl::FormatSink* s) {
        if (value == nullptr) {
            s->Append("[null]");
            return {true};
        }
        s->Append("[Device");
        const std::string& label = value->GetLabel();
        if (!label.empty()) {
            s->Append(absl::StrFormat(" \"%s\"", label));
        }
        s->Append("]");
        return {true};
    }

    absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
        const ApiObjectBase* value,
        const absl::FormatConversionSpec& spec,
        absl::FormatSink* s) {
        if (value == nullptr) {
            s->Append("[null]");
            return {true};
        }
        s->Append("[");
        if (value->IsError()) {
            s->Append("Invalid ");
        }
        s->Append(ObjectTypeAsString(value->GetType()));
        const std::string& label = value->GetLabel();
        if (!label.empty()) {
            s->Append(absl::StrFormat(" \"%s\"", label));
        }
        s->Append("]");
        return {true};
    }

    absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
        const TextureViewBase* value,
        const absl::FormatConversionSpec& spec,
        absl::FormatSink* s) {
        if (value == nullptr) {
            s->Append("[null]");
            return {true};
        }
        s->Append("[");
        if (value->IsError()) {
            s->Append("Invalid ");
        }
        s->Append(ObjectTypeAsString(value->GetType()));
        const std::string& label = value->GetLabel();
        if (!label.empty()) {
            s->Append(absl::StrFormat(" \"%s\"", label));
        }
        const std::string& textureLabel = value->GetTexture()->GetLabel();
        if (!textureLabel.empty()) {
            s->Append(absl::StrFormat(" of Texture \"%s\"", textureLabel));
        }
        s->Append("]");
        return {true};
    }

    //
    // Enums
    //

    absl::FormatConvertResult<absl::FormatConversionCharSet::kString>
    AbslFormatConvert(Aspect value, const absl::FormatConversionSpec& spec, absl::FormatSink* s) {
        if (value == Aspect::None) {
            s->Append("None");
            return {true};
        }

        bool first = true;

        if (value & Aspect::Color) {
            first = false;
            s->Append("Color");
            value &= ~Aspect::Color;
        }

        if (value & Aspect::Depth) {
            if (!first) {
                s->Append("|");
            }
            first = false;
            s->Append("Depth");
            value &= ~Aspect::Depth;
        }

        if (value & Aspect::Stencil) {
            if (!first) {
                s->Append("|");
            }
            first = false;
            s->Append("Stencil");
            value &= ~Aspect::Stencil;
        }

        // Output any remaining flags as a hex value
        if (static_cast<bool>(value)) {
            if (!first) {
                s->Append("|");
            }
            s->Append(absl::StrFormat("%x", static_cast<uint8_t>(value)));
        }

        return {true};
    }

    absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
        SampleTypeBit value,
        const absl::FormatConversionSpec& spec,
        absl::FormatSink* s) {
        if (value == SampleTypeBit::None) {
            s->Append("None");
            return {true};
        }

        bool first = true;

        if (value & SampleTypeBit::Float) {
            first = false;
            s->Append("Float");
            value &= ~SampleTypeBit::Float;
        }

        if (value & SampleTypeBit::UnfilterableFloat) {
            if (!first) {
                s->Append("|");
            }
            first = false;
            s->Append("UnfilterableFloat");
            value &= ~SampleTypeBit::UnfilterableFloat;
        }

        if (value & SampleTypeBit::Depth) {
            if (!first) {
                s->Append("|");
            }
            first = false;
            s->Append("Depth");
            value &= ~SampleTypeBit::Depth;
        }

        if (value & SampleTypeBit::Sint) {
            if (!first) {
                s->Append("|");
            }
            first = false;
            s->Append("Sint");
            value &= ~SampleTypeBit::Sint;
        }

        if (value & SampleTypeBit::Uint) {
            if (!first) {
                s->Append("|");
            }
            first = false;
            s->Append("Uint");
            value &= ~SampleTypeBit::Uint;
        }

        // Output any remaining flags as a hex value
        if (static_cast<bool>(value)) {
            if (!first) {
                s->Append("|");
            }
            s->Append(absl::StrFormat("%x", static_cast<uint8_t>(value)));
        }

        return {true};
    }

    absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
        BindingInfoType value,
        const absl::FormatConversionSpec& spec,
        absl::FormatSink* s) {
        switch (value) {
            case BindingInfoType::Buffer:
                s->Append("buffer");
                break;
            case BindingInfoType::Sampler:
                s->Append("sampler");
                break;
            case BindingInfoType::Texture:
                s->Append("texture");
                break;
            case BindingInfoType::StorageTexture:
                s->Append("storageTexture");
                break;
            case BindingInfoType::ExternalTexture:
                s->Append("externalTexture");
                break;
        }
        return {true};
    }

    absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
        SingleShaderStage value,
        const absl::FormatConversionSpec& spec,
        absl::FormatSink* s) {
        switch (value) {
            case SingleShaderStage::Compute:
                s->Append("Compute");
                break;
            case SingleShaderStage::Vertex:
                s->Append("Vertex");
                break;
            case SingleShaderStage::Fragment:
                s->Append("Fragment");
                break;
        }
        return {true};
    }

    absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
        VertexFormatBaseType value,
        const absl::FormatConversionSpec& spec,
        absl::FormatSink* s) {
        switch (value) {
            case VertexFormatBaseType::Float:
                s->Append("Float");
                break;
            case VertexFormatBaseType::Uint:
                s->Append("Uint");
                break;
            case VertexFormatBaseType::Sint:
                s->Append("Sint");
                break;
        }
        return {true};
    }

    absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
        InterStageComponentType value,
        const absl::FormatConversionSpec& spec,
        absl::FormatSink* s) {
        switch (value) {
            case InterStageComponentType::Float:
                s->Append("Float");
                break;
            case InterStageComponentType::Uint:
                s->Append("Uint");
                break;
            case InterStageComponentType::Sint:
                s->Append("Sint");
                break;
        }
        return {true};
    }

    absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
        InterpolationType value,
        const absl::FormatConversionSpec& spec,
        absl::FormatSink* s) {
        switch (value) {
            case InterpolationType::Perspective:
                s->Append("Perspective");
                break;
            case InterpolationType::Linear:
                s->Append("Linear");
                break;
            case InterpolationType::Flat:
                s->Append("Flat");
                break;
        }
        return {true};
    }

    absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
        InterpolationSampling value,
        const absl::FormatConversionSpec& spec,
        absl::FormatSink* s) {
        switch (value) {
            case InterpolationSampling::None:
                s->Append("None");
                break;
            case InterpolationSampling::Center:
                s->Append("Center");
                break;
            case InterpolationSampling::Centroid:
                s->Append("Centroid");
                break;
            case InterpolationSampling::Sample:
                s->Append("Sample");
                break;
        }
        return {true};
    }

}  // namespace dawn::native
