// 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.

#ifndef SRC_AST_MODULE_H_
#define SRC_AST_MODULE_H_

#include <functional>
#include <memory>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>

#include "src/ast/function.h"
#include "src/ast/variable.h"
#include "src/block_allocator.h"
#include "src/symbol_table.h"
#include "src/traits.h"
#include "src/type/alias_type.h"
#include "src/type/type_manager.h"

namespace tint {
namespace ast {

/// Represents all the source in a given program.
class Module {
 public:
  /// Constructor
  Module();

  /// Move constructor
  Module(Module&&);

  /// Move assignment operator
  /// @param rhs the Module to move
  /// @return this Module
  Module& operator=(Module&& rhs);

  /// Destructor
  ~Module();

  /// @return a deep copy of this module
  Module Clone() const;

  /// Clone this module into `ctx->mod` using the provided CloneContext
  /// The module will be cloned in this order:
  /// * Constructed types
  /// * Global variables
  /// * Functions
  /// @param ctx the clone context
  void Clone(CloneContext* ctx) const;

  /// Add a global variable to the module
  /// @param var the variable to add
  void AddGlobalVariable(Variable* var) { global_variables_.push_back(var); }
  /// @returns the global variables for the module
  const VariableList& global_variables() const { return global_variables_; }

  /// @returns the global variables for the module
  VariableList& global_variables() { return global_variables_; }

  /// Adds a constructed type to the module.
  /// The type must be an alias or a struct.
  /// @param type the constructed type to add
  void AddConstructedType(type::Type* type) {
    constructed_types_.push_back(type);
  }
  /// @returns the constructed types in the module
  const std::vector<type::Type*>& constructed_types() const {
    return constructed_types_;
  }

  /// Adds a function to the module
  /// @param func the function
  void AddFunction(Function* func) { functions_.push_back(func); }
  /// @returns the modules functions
  const FunctionList& functions() const { return functions_; }
  /// Returns the function with the given name
  /// @param sym the function symbol to search for
  /// @returns the associated function or nullptr if none exists
  Function* FindFunctionBySymbol(Symbol sym) const;
  /// Returns the function with the given name
  /// @param sym the function symbol to search for
  /// @param stage the pipeline stage
  /// @returns the associated function or nullptr if none exists
  Function* FindFunctionBySymbolAndStage(Symbol sym, PipelineStage stage) const;
  /// @param stage the pipeline stage
  /// @returns true if the module contains an entrypoint function with the given
  /// stage
  bool HasStage(PipelineStage stage) const;

  /// @returns true if all required fields in the AST are present.
  bool IsValid() const;

  /// @returns a string representation of the module
  std::string to_str() const;

  /// Creates a new Node owned by the Module. When the Module is
  /// destructed, the Node will also be destructed.
  /// @param args the arguments to pass to the type constructor
  /// @returns the node pointer
  template <typename T, typename... ARGS>
  traits::EnableIfIsType<T, Node>* create(ARGS&&... args) {
    return ast_nodes_.Create<T>(std::forward<ARGS>(args)...);
  }

  /// Creates a new type::Type owned by the Module.
  /// When the Module is destructed, owned Module and the returned
  /// `Type` will also be destructed.
  /// Types are unique (de-aliased), and so calling create() for the same `T`
  /// and arguments will return the same pointer.
  /// @warning Use this method to acquire a type only if all of its type
  /// information is provided in the constructor arguments `args`.<br>
  /// If the type requires additional configuration after construction that
  /// affect its fundamental type, build the type with `std::make_unique`, make
  /// any necessary alterations and then call unique_type() instead.
  /// @param args the arguments to pass to the type constructor
  /// @returns the de-aliased type pointer
  template <typename T, typename... ARGS>
  traits::EnableIfIsType<T, type::Type>* create(ARGS&&... args) {
    static_assert(std::is_base_of<type::Type, T>::value,
                  "T does not derive from type::Type");
    return type_mgr_.Get<T>(std::forward<ARGS>(args)...);
  }

  /// Moves the type `ty` to the Module, returning a pointer to the unique
  /// (de-aliased) type.
  /// When the Module is destructed, the returned `Type` will also be
  /// destructed.
  /// @see create()
  /// @param ty the type to add to the module
  /// @returns the de-aliased type pointer
  template <typename T>
  traits::EnableIfIsType<T, type::Type>* unique_type(std::unique_ptr<T> ty) {
    return static_cast<T*>(type_mgr_.Get(std::move(ty)));
  }

  /// Returns all the declared types in the module
  /// @returns the mapping from name string to type.
  const std::unordered_map<std::string, std::unique_ptr<type::Type>>& types() {
    return type_mgr_.types();
  }

  /// @returns all the declared nodes in the module
  BlockAllocator<Node>::View nodes() { return ast_nodes_.Objects(); }

  /// Registers `name` as a symbol
  /// @param name the name to register
  /// @returns the symbol for the `name`. If `name` is already registered the
  /// previously generated symbol will be returned.
  Symbol RegisterSymbol(const std::string& name);

  /// Returns the symbol for `name`
  /// @param name the name to lookup
  /// @returns the symbol for name or symbol::kInvalid
  Symbol GetSymbol(const std::string& name) const;

  /// Returns the `name` for `sym`
  /// @param sym the symbol to retrieve the name for
  /// @returns the use provided `name` for the symbol or "" if not found
  std::string SymbolToName(const Symbol sym) const;

 private:
  Module(const Module&) = delete;

  SymbolTable symbol_table_;
  VariableList global_variables_;
  // The constructed types are owned by the type manager
  std::vector<type::Type*> constructed_types_;
  FunctionList functions_;
  BlockAllocator<Node> ast_nodes_;
  type::Manager type_mgr_;
};

}  // namespace ast
}  // namespace tint

#endif  // SRC_AST_MODULE_H_
