// 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_TYPE_DETERMINER_H_
#define SRC_TYPE_DETERMINER_H_

#include <string>
#include <unordered_map>

#include "src/ast/module.h"
#include "src/ast/type/storage_texture_type.h"
#include "src/context.h"
#include "src/scope_stack.h"

namespace tint {
namespace ast {

class ArrayAccessorExpression;
class BinaryExpression;
class BitcastExpression;
class CallExpression;
class ConstructorExpression;
class Function;
class IdentifierExpression;
class MemberAccessorExpression;
class UnaryOpExpression;
class Variable;

}  // namespace ast

/// Determines types for all items in the given tint module
class TypeDeterminer {
 public:
  /// Constructor
  /// @param ctx the tint context
  /// @param mod the module to update with typing information
  TypeDeterminer(Context* ctx, ast::Module* mod);
  ~TypeDeterminer();

  /// @returns error messages from the type determiner
  const std::string& error() { return error_; }

  /// @returns true if the type determiner was successful
  bool Determine();
  /// Determines type information for functions
  /// @param funcs the functions to check
  /// @returns true if the determination was successful
  bool DetermineFunctions(const ast::FunctionList& funcs);
  /// Determines type information for a function
  /// @param func the function to check
  /// @returns true if the determination was successful
  bool DetermineFunction(ast::Function* func);
  /// Determines type information for a set of statements
  /// @param stmts the statements to check
  /// @returns true if the determination was successful
  bool DetermineStatements(const ast::BlockStatement* stmts);
  /// Determines type information for a statement
  /// @param stmt the statement to check
  /// @returns true if the determination was successful
  bool DetermineResultType(ast::Statement* stmt);
  /// Determines type information for an expression list
  /// @param list the expression list to check
  /// @returns true if the determination was successful
  bool DetermineResultType(const ast::ExpressionList& list);
  /// Determines type information for an expression
  /// @param expr the expression to check
  /// @returns true if the determination was successful
  bool DetermineResultType(ast::Expression* expr);
  /// Determines the storage class for variables. This assumes that it is only
  /// called for things in function scope, not module scope.
  /// @param stmt the statement to check
  /// @returns false on error
  bool DetermineVariableStorageClass(ast::Statement* stmt);
  /// Determines the result type based off a storage texture format
  /// @param tex the storage texture
  /// @returns false on error
  bool DetermineStorageTextureSubtype(ast::type::StorageTextureType* tex);

  /// Testing method to set a given variable into the type stack
  /// @param var the variable to set
  void RegisterVariableForTesting(ast::Variable* var) {
    variable_stack_.set(var->name(), var);
  }

  /// Retrieves information for the requested import.
  /// @param src the source of the import
  /// @param path the import path
  /// @param name the method name to get information on
  /// @param params the parameters to the method call
  /// @param id out parameter for the external call ID. Must not be a nullptr.
  /// @returns the return type of |name| in |path| or nullptr on error.
  ast::type::Type* GetImportData(const Source& src,
                                 const std::string& path,
                                 const std::string& name,
                                 const ast::ExpressionList& params,
                                 uint32_t* id);

  /// Sets the intrinsic data information for the identifier if needed
  /// @param ident the identifier expression
  /// @returns true if an intrinsic was set
  bool SetIntrinsicIfNeeded(ast::IdentifierExpression* ident);

 private:
  void set_error(const Source& src, const std::string& msg);
  void set_referenced_from_function_if_needed(ast::Variable* var);
  void set_entry_points(const std::string& fn_name, const std::string& ep_name);

  bool DetermineArrayAccessor(ast::ArrayAccessorExpression* expr);
  bool DetermineBinary(ast::BinaryExpression* expr);
  bool DetermineBitcast(ast::BitcastExpression* expr);
  bool DetermineCall(ast::CallExpression* expr);
  bool DetermineConstructor(ast::ConstructorExpression* expr);
  bool DetermineIdentifier(ast::IdentifierExpression* expr);
  bool DetermineIntrinsic(ast::IdentifierExpression* name,
                          ast::CallExpression* expr);
  bool DetermineMemberAccessor(ast::MemberAccessorExpression* expr);
  bool DetermineUnaryOp(ast::UnaryOpExpression* expr);

  Context& ctx_;
  ast::Module* mod_;
  std::string error_;
  ScopeStack<ast::Variable*> variable_stack_;
  std::unordered_map<std::string, ast::Function*> name_to_function_;
  ast::Function* current_function_ = nullptr;

  // Map from caller functions to callee functions.
  std::unordered_map<std::string, std::vector<std::string>> caller_to_callee_;
};

}  // namespace tint

#endif  // SRC_TYPE_DETERMINER_H_
