// Copyright 2021 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/ast/module.h"

#include <utility>

#include "src/tint/ast/type_decl.h"
#include "src/tint/program_builder.h"

TINT_INSTANTIATE_TYPEINFO(tint::ast::Module);

namespace tint::ast {

Module::Module(ProgramID pid, NodeID nid, const Source& src) : Base(pid, nid, src) {}

Module::Module(ProgramID pid,
               NodeID nid,
               const Source& src,
               utils::VectorRef<const ast::Node*> global_decls)
    : Base(pid, nid, src), global_declarations_(std::move(global_decls)) {
    for (auto* decl : global_declarations_) {
        if (decl == nullptr) {
            continue;
        }
        diag::List diags;
        BinGlobalDeclaration(decl, diags);
    }
}

Module::~Module() = default;

const ast::TypeDecl* Module::LookupType(Symbol name) const {
    for (auto* ty : TypeDecls()) {
        if (ty->name->symbol == name) {
            return ty;
        }
    }
    return nullptr;
}

void Module::AddGlobalDeclaration(const tint::ast::Node* decl) {
    diag::List diags;
    BinGlobalDeclaration(decl, diags);
    global_declarations_.Push(decl);
}

void Module::BinGlobalDeclaration(const tint::ast::Node* decl, diag::List& diags) {
    Switch(
        decl,  //
        [&](const ast::TypeDecl* type) {
            TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, type, program_id);
            type_decls_.Push(type);
        },
        [&](const Function* func) {
            TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, func, program_id);
            functions_.Push(func);
        },
        [&](const Variable* var) {
            TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, var, program_id);
            global_variables_.Push(var);
        },
        [&](const DiagnosticDirective* diagnostic) {
            TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, diagnostic, program_id);
            diagnostic_directives_.Push(diagnostic);
        },
        [&](const Enable* enable) {
            TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, enable, program_id);
            enables_.Push(enable);
        },
        [&](const ConstAssert* assertion) {
            TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, assertion, program_id);
            const_asserts_.Push(assertion);
        },
        [&](Default) { TINT_ICE(AST, diags) << "Unknown global declaration type"; });
}

void Module::AddDiagnosticDirective(const ast::DiagnosticDirective* directive) {
    TINT_ASSERT(AST, directive);
    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, directive, program_id);
    global_declarations_.Push(directive);
    diagnostic_directives_.Push(directive);
}

void Module::AddEnable(const ast::Enable* enable) {
    TINT_ASSERT(AST, enable);
    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, enable, program_id);
    global_declarations_.Push(enable);
    enables_.Push(enable);
}

void Module::AddGlobalVariable(const ast::Variable* var) {
    TINT_ASSERT(AST, var);
    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, var, program_id);
    global_variables_.Push(var);
    global_declarations_.Push(var);
}

void Module::AddConstAssert(const ConstAssert* assertion) {
    TINT_ASSERT(AST, assertion);
    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, assertion, program_id);
    const_asserts_.Push(assertion);
    global_declarations_.Push(assertion);
}

void Module::AddTypeDecl(const ast::TypeDecl* type) {
    TINT_ASSERT(AST, type);
    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, type, program_id);
    type_decls_.Push(type);
    global_declarations_.Push(type);
}

void Module::AddFunction(const ast::Function* func) {
    TINT_ASSERT(AST, func);
    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, func, program_id);
    functions_.Push(func);
    global_declarations_.Push(func);
}

const Module* Module::Clone(CloneContext* ctx) const {
    auto* out = ctx->dst->create<Module>();
    out->Copy(ctx, this);
    return out;
}

void Module::Copy(CloneContext* ctx, const Module* src) {
    ctx->Clone(global_declarations_, src->global_declarations_);

    // During the clone, declarations may have been placed into the module.
    // Clear everything out, as we're about to re-bin the declarations.
    type_decls_.Clear();
    functions_.Clear();
    global_variables_.Clear();
    enables_.Clear();
    diagnostic_directives_.Clear();

    for (auto* decl : global_declarations_) {
        if (TINT_UNLIKELY(!decl)) {
            TINT_ICE(AST, ctx->dst->Diagnostics()) << "src global declaration was nullptr";
            continue;
        }
        BinGlobalDeclaration(decl, ctx->dst->Diagnostics());
    }
}

}  // namespace tint::ast
