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

#include <sstream>

#include "src/ast/clone_context.h"
#include "src/ast/type/struct_type.h"

namespace tint {
namespace ast {

Module::Module() = default;

Module::Module(Module&&) = default;

Module& Module::operator=(Module&& rhs) = default;

Module::~Module() = default;

Module Module::Clone() const {
  Module out;
  CloneContext(&out, this).Clone();
  return out;
}

void Module::Clone(CloneContext* ctx) const {
  for (auto* ty : constructed_types_) {
    ctx->mod->constructed_types_.emplace_back(ctx->Clone(ty));
  }
  for (auto* var : global_variables_) {
    ctx->mod->global_variables_.emplace_back(ctx->Clone(var));
  }
  for (auto* func : functions_) {
    ctx->mod->functions_.emplace_back(ctx->Clone(func));
  }
}

Function* Module::FindFunctionBySymbol(Symbol sym) const {
  for (auto* func : functions_) {
    if (func->symbol() == sym) {
      return func;
    }
  }
  return nullptr;
}

Function* Module::FindFunctionBySymbolAndStage(Symbol sym,
                                               PipelineStage stage) const {
  for (auto* func : functions_) {
    if (func->symbol() == sym && func->pipeline_stage() == stage) {
      return func;
    }
  }
  return nullptr;
}

bool Module::HasStage(ast::PipelineStage stage) const {
  for (auto* func : functions_) {
    if (func->pipeline_stage() == stage) {
      return true;
    }
  }
  return false;
}

Symbol Module::RegisterSymbol(const std::string& name) {
  return symbol_table_.Register(name);
}

Symbol Module::GetSymbol(const std::string& name) const {
  return symbol_table_.GetSymbol(name);
}

std::string Module::SymbolToName(const Symbol sym) const {
  return symbol_table_.NameFor(sym);
}

bool Module::IsValid() const {
  for (auto* var : global_variables_) {
    if (var == nullptr || !var->IsValid()) {
      return false;
    }
  }
  for (auto* const ty : constructed_types_) {
    if (ty == nullptr) {
      return false;
    }
    if (auto* alias = ty->As<type::Alias>()) {
      if (alias->type() == nullptr) {
        return false;
      }
      if (auto* str = alias->type()->As<type::Struct>()) {
        if (!str->symbol().IsValid()) {
          return false;
        }
      }
    } else if (auto* str = ty->As<type::Struct>()) {
      if (!str->symbol().IsValid()) {
        return false;
      }
    } else {
      return false;
    }
  }
  for (auto* func : functions_) {
    if (func == nullptr || !func->IsValid()) {
      return false;
    }
  }
  return true;
}

std::string Module::to_str() const {
  std::ostringstream out;

  out << "Module{" << std::endl;
  const auto indent = 2;
  for (auto* const ty : constructed_types_) {
    for (size_t i = 0; i < indent; ++i) {
      out << " ";
    }
    if (auto* alias = ty->As<type::Alias>()) {
      out << alias->symbol().to_str() << " -> " << alias->type()->type_name()
          << std::endl;
      if (auto* str = alias->type()->As<type::Struct>()) {
        str->impl()->to_str(out, indent);
      }
    } else if (auto* str = ty->As<type::Struct>()) {
      out << str->symbol().to_str() << " ";
      str->impl()->to_str(out, indent);
    }
  }
  for (auto* var : global_variables_) {
    var->to_str(out, indent);
  }
  for (auto* func : functions_) {
    func->to_str(out, indent);
  }
  out << "}" << std::endl;

  return out.str();
}

}  // namespace ast
}  // namespace tint
