// 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 <string>

#include "dawn/native/AttachmentState.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};
    }

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

        s->Append("{ colorFormats: [");

        ColorAttachmentIndex nextColorIndex(uint8_t(0));

        bool needsComma = false;
        for (ColorAttachmentIndex i : IterateBitSet(value->GetColorAttachmentsMask())) {
            while (nextColorIndex < i) {
                s->Append(absl::StrFormat("%s, ", wgpu::TextureFormat::Undefined));
                nextColorIndex++;
                needsComma = false;
            }

            if (needsComma) {
                s->Append(", ");
            }

            s->Append(absl::StrFormat("%s", value->GetColorAttachmentFormat(i)));

            nextColorIndex++;
            needsComma = true;
        }

        s->Append("], ");

        if (value->HasDepthStencilAttachment()) {
            s->Append(absl::StrFormat("depthStencilFormat: %s, ", value->GetDepthStencilFormat()));
        }

        s->Append(absl::StrFormat("sampleCount: %u }", value->GetSampleCount()));

        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
