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

#ifndef SRC_SEM_INFO_H_
#define SRC_SEM_INFO_H_

#include <type_traits>
#include <unordered_map>

#include "src/debug.h"
#include "src/sem/node.h"
#include "src/sem/type_mappings.h"

namespace tint::sem {

// Forward declarations
class Module;

/// Info holds all the resolved semantic information for a Program.
class Info {
 public:
  /// Placeholder type used by Get() to provide a default value for EXPLICIT_SEM
  using InferFromAST = std::nullptr_t;

  /// Resolves to the return type of the Get() method given the desired sementic
  /// type and AST type.
  template <typename SEM, typename AST_OR_TYPE>
  using GetResultType =
      std::conditional_t<std::is_same<SEM, InferFromAST>::value,
                         SemanticNodeTypeFor<AST_OR_TYPE>,
                         SEM>;

  /// Constructor
  Info();

  /// Move constructor
  Info(Info&&);

  /// Destructor
  ~Info();

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

  /// Get looks up the semantic information for the AST or type node `node`.
  /// @param node the AST or type node
  /// @returns a pointer to the semantic node if found, otherwise nullptr
  template <typename SEM = InferFromAST,
            typename AST_OR_TYPE = CastableBase,
            typename RESULT = GetResultType<SEM, AST_OR_TYPE>>
  const RESULT* Get(const AST_OR_TYPE* node) const {
    auto it = map_.find(node);
    if (it == map_.end()) {
      return nullptr;
    }
    return As<RESULT>(it->second);
  }

  /// Add registers the semantic node `sem_node` for the AST or type node
  /// `node`.
  /// @param node the AST or type node
  /// @param sem_node the semantic node
  template <typename AST_OR_TYPE>
  void Add(const AST_OR_TYPE* node,
           const SemanticNodeTypeFor<AST_OR_TYPE>* sem_node) {
    // Check there's no semantic info already existing for the node
    TINT_ASSERT(Semantic, Get(node) == nullptr);
    map_.emplace(node, sem_node);
  }

  /// Wrap returns a new Info created with the contents of `inner`.
  /// The Info returned by Wrap is intended to temporarily extend the contents
  /// of an existing immutable Info.
  /// As the copied contents are owned by `inner`, `inner` must not be
  /// destructed or assigned while using the returned Info.
  /// @param inner the immutable Info to extend
  /// @return the Info that wraps `inner`
  static Info Wrap(const Info& inner) {
    Info out;
    out.map_ = inner.map_;
    out.module_ = inner.module_;
    return out;
  }

  /// Assigns the semantic module.
  /// @param module the module to assign.
  void SetModule(sem::Module* module) { module_ = module; }

  /// @returns the semantic module.
  const sem::Module* Module() const { return module_; }

 private:
  // TODO(crbug.com/tint/724): Once finished, this map should be:
  // std::unordered_map<const ast::Node*, const sem::Node*>
  std::unordered_map<const CastableBase*, const CastableBase*> map_;
  // The semantic module
  sem::Module* module_ = nullptr;
};

}  // namespace tint::sem

#endif  // SRC_SEM_INFO_H_
