// Copyright 2022 The Tint 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/tint/lang/wgsl/resolver/sem_helper.h"

#include "src/tint/lang/wgsl/sem/builtin_enum_expression.h"
#include "src/tint/lang/wgsl/sem/function.h"
#include "src/tint/lang/wgsl/sem/function_expression.h"
#include "src/tint/lang/wgsl/sem/type_expression.h"
#include "src/tint/lang/wgsl/sem/value_expression.h"
#include "src/tint/utils/rtti/switch.h"

namespace tint::resolver {

SemHelper::SemHelper(ProgramBuilder* builder) : builder_(builder) {}

SemHelper::~SemHelper() = default;

std::string SemHelper::TypeNameOf(const core::type::Type* ty) const {
    return RawTypeNameOf(ty->UnwrapRef());
}

std::string SemHelper::RawTypeNameOf(const core::type::Type* ty) const {
    return ty->FriendlyName();
}

core::type::Type* SemHelper::TypeOf(const ast::Expression* expr) const {
    auto* sem = GetVal(expr);
    return sem ? const_cast<core::type::Type*>(sem->Type()) : nullptr;
}

std::string SemHelper::Describe(const sem::Expression* expr) const {
    return Switch(
        expr,  //
        [&](const sem::VariableUser* var_expr) {
            auto* variable = var_expr->Variable()->Declaration();
            auto name = variable->name->symbol.Name();
            auto* kind = Switch(
                variable,                                            //
                [&](const ast::Var*) { return "var"; },              //
                [&](const ast::Let*) { return "let"; },              //
                [&](const ast::Const*) { return "const"; },          //
                [&](const ast::Parameter*) { return "parameter"; },  //
                [&](const ast::Override*) { return "override"; },    //
                [&](Default) { return "variable"; });
            return std::string(kind) + " '" + name + "'";
        },
        [&](const sem::ValueExpression* val_expr) {
            auto type = val_expr->Type()->FriendlyName();
            return "value expression of type '" + type + "'";
        },
        [&](const sem::TypeExpression* ty_expr) {
            auto name = ty_expr->Type()->FriendlyName();
            return "type '" + name + "'";
        },
        [&](const sem::FunctionExpression* fn_expr) {
            auto* fn = fn_expr->Function()->Declaration();
            auto name = fn->name->symbol.Name();
            return "function '" + name + "'";
        },
        [&](const sem::BuiltinEnumExpression<core::Access>* access) {
            return "access '" + tint::ToString(access->Value()) + "'";
        },
        [&](const sem::BuiltinEnumExpression<core::AddressSpace>* addr) {
            return "address space '" + tint::ToString(addr->Value()) + "'";
        },
        [&](const sem::BuiltinEnumExpression<core::BuiltinValue>* builtin) {
            return "builtin value '" + tint::ToString(builtin->Value()) + "'";
        },
        [&](const sem::BuiltinEnumExpression<core::InterpolationSampling>* fmt) {
            return "interpolation sampling '" + tint::ToString(fmt->Value()) + "'";
        },
        [&](const sem::BuiltinEnumExpression<core::InterpolationType>* fmt) {
            return "interpolation type '" + tint::ToString(fmt->Value()) + "'";
        },
        [&](const sem::BuiltinEnumExpression<core::TexelFormat>* fmt) {
            return "texel format '" + tint::ToString(fmt->Value()) + "'";
        },
        [&](Default) -> std::string {
            TINT_ICE() << "unhandled sem::Expression type: "
                       << (expr ? expr->TypeInfo().name : "<null>");
            return "<unknown>";
        });
}

void SemHelper::ErrorUnexpectedExprKind(const sem::Expression* expr,
                                        std::string_view wanted) const {
    AddError("cannot use " + Describe(expr) + " as " + std::string(wanted),
             expr->Declaration()->source);
    NoteDeclarationSource(expr->Declaration());
}

void SemHelper::ErrorExpectedValueExpr(const sem::Expression* expr) const {
    ErrorUnexpectedExprKind(expr, "value");
    if (auto* ty_expr = expr->As<sem::TypeExpression>()) {
        if (auto* ident = ty_expr->Declaration()->As<ast::IdentifierExpression>()) {
            AddNote("are you missing '()' for value constructor?", ident->source.End());
        }
    }
}

void SemHelper::NoteDeclarationSource(const ast::Node* node) const {
    if (!node) {
        return;
    }

    Switch(
        Get(node),  //
        [&](const sem::VariableUser* var_expr) { node = var_expr->Variable()->Declaration(); },
        [&](const sem::TypeExpression* ty_expr) {
            Switch(ty_expr->Type(),  //
                   [&](const sem::Struct* s) { node = s->Declaration(); });
        },
        [&](const sem::FunctionExpression* fn_expr) { node = fn_expr->Function()->Declaration(); });

    Switch(
        node,
        [&](const ast::Struct* n) {
            AddNote("struct '" + n->name->symbol.Name() + "' declared here", n->source);
        },
        [&](const ast::Alias* n) {
            AddNote("alias '" + n->name->symbol.Name() + "' declared here", n->source);
        },
        [&](const ast::Var* n) {
            AddNote("var '" + n->name->symbol.Name() + "' declared here", n->source);
        },
        [&](const ast::Let* n) {
            AddNote("let '" + n->name->symbol.Name() + "' declared here", n->source);
        },
        [&](const ast::Override* n) {
            AddNote("override '" + n->name->symbol.Name() + "' declared here", n->source);
        },
        [&](const ast::Const* n) {
            AddNote("const '" + n->name->symbol.Name() + "' declared here", n->source);
        },
        [&](const ast::Parameter* n) {
            AddNote("parameter '" + n->name->symbol.Name() + "' declared here", n->source);
        },
        [&](const ast::Function* n) {
            AddNote("function '" + n->name->symbol.Name() + "' declared here", n->source);
        });
}

void SemHelper::AddError(const std::string& msg, const Source& source) const {
    builder_->Diagnostics().add_error(diag::System::Resolver, msg, source);
}

void SemHelper::AddWarning(const std::string& msg, const Source& source) const {
    builder_->Diagnostics().add_warning(diag::System::Resolver, msg, source);
}

void SemHelper::AddNote(const std::string& msg, const Source& source) const {
    builder_->Diagnostics().add_note(diag::System::Resolver, msg, source);
}
}  // namespace tint::resolver
