// 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,
               std::vector<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 == name) {
            return ty;
        }
    }
    return nullptr;
}

void Module::AddGlobalDeclaration(const tint::ast::Node* decl) {
    diag::List diags;
    BinGlobalDeclaration(decl, diags);
    global_declarations_.emplace_back(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_back(type);
        },
        [&](const Function* func) {
            TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, func, program_id);
            functions_.push_back(func);
        },
        [&](const Variable* var) {
            TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, var, program_id);
            global_variables_.push_back(var);
        },
        [&](const Enable* enable) {
            TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, enable, program_id);
            enables_.push_back(enable);
        },
        [&](Default) { TINT_ICE(AST, diags) << "Unknown global declaration type"; });
}

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_back(enable);
    enables_.push_back(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_back(var);
    global_declarations_.push_back(var);
}

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_back(type);
    global_declarations_.push_back(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_back(func);
    global_declarations_.push_back(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();

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

}  // namespace tint::ast
