// Copyright 2022 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "src/tint/lang/wgsl/resolver/sem_helper.h"

#include "src/tint/lang/wgsl/resolver/incomplete_type.h"
#include "src/tint/lang/wgsl/resolver/unresolved_identifier.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"
#include "src/tint/utils/text/styled_text.h"
#include "src/tint/utils/text/text_style.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;
}

sem::TypeExpression* SemHelper::AsTypeExpression(sem::Expression* expr) const {
    if (TINT_UNLIKELY(!expr)) {
        return nullptr;
    }

    auto* ty_expr = expr->As<sem::TypeExpression>();
    if (TINT_UNLIKELY(!ty_expr)) {
        ErrorUnexpectedExprKind(expr, "type");
        return nullptr;
    }

    auto* type = ty_expr->Type();
    if (auto* incomplete = type->As<IncompleteType>(); TINT_UNLIKELY(incomplete)) {
        AddError(expr->Declaration()->source.End())
            << "expected " << style::Code("<") << " for " << style::Type(incomplete->builtin);
        return nullptr;
    }

    return ty_expr;
}

StyledText SemHelper::Describe(const sem::Expression* expr) const {
    StyledText text;

    Switch(
        expr,  //
        [&](const sem::VariableUser* var_expr) {
            auto* variable = var_expr->Variable()->Declaration();
            auto name = variable->name->symbol.NameView();
            Switch(
                variable,                                                                         //
                [&](const ast::Var*) { text << style::Keyword("var") << style::Code(" "); },      //
                [&](const ast::Let*) { text << style::Keyword("let") << style::Code(" "); },      //
                [&](const ast::Const*) { text << style::Keyword("const") << style::Code(" "); },  //
                [&](const ast::Parameter*) { text << "parameter "; },                             //
                [&](const ast::Override*) {
                    text << style::Keyword("override") << style::Code(" ");
                },  //
                [&](Default) { text << "variable "; });
            text << style::Variable(name);
        },
        [&](const sem::ValueExpression* val_expr) {
            text << "value of type " << style::Type(val_expr->Type()->FriendlyName());
        },
        [&](const sem::TypeExpression* ty_expr) {
            text << "type " << style::Type(ty_expr->Type()->FriendlyName());
        },
        [&](const sem::FunctionExpression* fn_expr) {
            auto* fn = fn_expr->Function()->Declaration();
            text << "function " << style::Function(fn->name->symbol.NameView());
        },
        [&](const sem::BuiltinEnumExpression<wgsl::BuiltinFn>* fn) {
            text << "builtin function " << style::Function(fn->Value());
        },
        [&](const sem::BuiltinEnumExpression<core::Access>* access) {
            text << "access " << style::Enum(access->Value());
        },
        [&](const sem::BuiltinEnumExpression<core::AddressSpace>* addr) {
            text << "address space " << style::Enum(addr->Value());
        },
        [&](const sem::BuiltinEnumExpression<core::BuiltinValue>* builtin) {
            text << "builtin value " << style::Enum(builtin->Value());
        },
        [&](const sem::BuiltinEnumExpression<core::InterpolationSampling>* fmt) {
            text << "interpolation sampling " << style::Enum(fmt->Value());
        },
        [&](const sem::BuiltinEnumExpression<core::InterpolationType>* fmt) {
            text << "interpolation type " << style::Enum(fmt->Value());
        },
        [&](const sem::BuiltinEnumExpression<core::TexelFormat>* fmt) {
            text << "texel format " << style::Enum(fmt->Value());
        },
        [&](const UnresolvedIdentifier* ui) {
            auto name = ui->Identifier()->identifier->symbol.NameView();
            text << "unresolved identifier " << style::Code(name);
        },  //
        TINT_ICE_ON_NO_MATCH);

    return text;
}

void SemHelper::ErrorUnexpectedExprKind(
    const sem::Expression* expr,
    std::string_view wanted,
    tint::Slice<const std::string_view> suggestions /* = Empty */) const {
    if (auto* ui = expr->As<UnresolvedIdentifier>()) {
        auto* ident = ui->Identifier();
        auto name = ident->identifier->symbol.NameView();
        AddError(ident->source) << "unresolved " << wanted << " " << style::Code(name);
        if (!suggestions.IsEmpty()) {
            // Filter out suggestions that have a leading underscore.
            Vector<std::string_view, 8> filtered;
            for (auto str : suggestions) {
                if (str[0] != '_') {
                    filtered.Push(str);
                }
            }
            auto& note = AddNote(ident->source);
            SuggestAlternativeOptions opts;
            opts.alternatives_style = style::Enum;
            SuggestAlternatives(name, filtered.Slice(), note.message, opts);
        }
        return;
    }

    AddError(expr->Declaration()->source) << "cannot use " << Describe(expr) << " as " << wanted;
    NoteDeclarationSource(expr->Declaration());
}

void SemHelper::ErrorExpectedValueExpr(const sem::Expression* expr) const {
    ErrorUnexpectedExprKind(expr, "value");
    if (auto* ident = expr->Declaration()->As<ast::IdentifierExpression>()) {
        if (expr->IsAnyOf<sem::FunctionExpression, sem::TypeExpression,
                          sem::BuiltinEnumExpression<wgsl::BuiltinFn>>()) {
            AddNote(ident->source.End())
                << "are you missing " << style::Code("()") << style::Plain("?");
        }
    }
}

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(n->source) << style::Keyword("struct ")
                               << style::Type(n->name->symbol.NameView()) << " declared here";
        },
        [&](const ast::Alias* n) {
            AddNote(n->source) << style::Keyword("alias ")
                               << style::Type(n->name->symbol.NameView()) << " declared here";
        },
        [&](const ast::Var* n) {
            AddNote(n->source) << style::Keyword("var ")
                               << style::Variable(n->name->symbol.NameView()) << " declared here";
        },
        [&](const ast::Let* n) {
            AddNote(n->source) << style::Keyword("let ")
                               << style::Variable(n->name->symbol.NameView()) << " declared here";
        },
        [&](const ast::Override* n) {
            AddNote(n->source) << style::Keyword("override ")
                               << style::Variable(n->name->symbol.NameView()) << " declared here";
        },
        [&](const ast::Const* n) {
            AddNote(n->source) << style::Keyword("const ")
                               << style::Variable(n->name->symbol.NameView()) << " declared here";
        },
        [&](const ast::Parameter* n) {
            AddNote(n->source) << "parameter " << style::Variable(n->name->symbol.NameView())
                               << " declared here";
        },
        [&](const ast::Function* n) {
            AddNote(n->source) << "function " << style::Function(n->name->symbol.NameView())
                               << " declared here";
        });
}

diag::Diagnostic& SemHelper::AddError(const Source& source) const {
    return builder_->Diagnostics().AddError(source);
}

diag::Diagnostic& SemHelper::AddWarning(const Source& source) const {
    return builder_->Diagnostics().AddWarning(source);
}

diag::Diagnostic& SemHelper::AddNote(const Source& source) const {
    return builder_->Diagnostics().AddNote(source);
}
}  // namespace tint::resolver
