// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef TOOLS_GN_TOOL_H_
#define TOOLS_GN_TOOL_H_

#include <string>

#include "base/logging.h"
#include "base/macros.h"
#include "tools/gn/label.h"
#include "tools/gn/label_ptr.h"
#include "tools/gn/scope.h"
#include "tools/gn/source_file.h"
#include "tools/gn/substitution_list.h"
#include "tools/gn/substitution_pattern.h"

class ParseNode;
class Pool;
class Target;
class Toolchain;

class CTool;
class GeneralTool;
class RustTool;

// To add a new Tool category, create a subclass implementing SetComplete()
// Add a new category to ToolCategories
// Add a GetAs* function
class Tool {
 public:
  static const char* kToolNone;

  virtual ~Tool();

  // Manual RTTI and required functions ---------------------------------------
  //
  // To implement a new tool category to compile binaries in a different way,
  // inherit this class, implement the following functions, and add the
  // appropriate ToolTypes and RTTI getters. New tools will also need to
  // implement a corresponding class inheriting NinjaBinaryTargetWriter that
  // does the actual rule writing.

  // Initialize tool from a scope. Child classes should override this function
  // and call the parent.
  bool InitTool(Scope* block_scope, Toolchain* toolchain, Err* err);

  // Validate the char* passed to the creation.
  virtual bool ValidateName(const char* name) const = 0;

  // Called when the toolchain is saving this tool, after everything is filled
  // in.
  virtual void SetComplete() = 0;

  // Validate substitutions in this tool.
  virtual bool ValidateSubstitution(const Substitution* sub_type) const = 0;

  // Manual RTTI
  virtual CTool* AsC();
  virtual const CTool* AsC() const;
  virtual GeneralTool* AsGeneral();
  virtual const GeneralTool* AsGeneral() const;
  virtual RustTool* AsRust();
  virtual const RustTool* AsRust() const;

  // Basic information ---------------------------------------------------------

  const ParseNode* defined_from() const { return defined_from_; }
  void set_defined_from(const ParseNode* df) { defined_from_ = df; }

  const char* name() const { return name_; }

  // Getters/setters ----------------------------------------------------------
  //
  // After the tool has had its attributes set, the caller must call
  // SetComplete(), at which point no other changes can be made.

  // Command to run.
  const SubstitutionPattern& command() const { return command_; }
  void set_command(SubstitutionPattern cmd) {
    DCHECK(!complete_);
    command_ = std::move(cmd);
  }

  // Launcher for the command (e.g. goma)
  const std::string& command_launcher() const {
    return command_launcher_;
  }
  void set_command_launcher(std::string l) {
    DCHECK(!complete_);
    command_launcher_ = std::move(l);
  }

  // Should include a leading "." if nonempty.
  const std::string& default_output_extension() const {
    return default_output_extension_;
  }
  void set_default_output_extension(std::string ext) {
    DCHECK(!complete_);
    DCHECK(ext.empty() || ext[0] == '.');
    default_output_extension_ = std::move(ext);
  }

  const SubstitutionPattern& default_output_dir() const {
    return default_output_dir_;
  }
  void set_default_output_dir(SubstitutionPattern dir) {
    DCHECK(!complete_);
    default_output_dir_ = std::move(dir);
  }

  // Dependency file (if supported).
  const SubstitutionPattern& depfile() const { return depfile_; }
  void set_depfile(SubstitutionPattern df) {
    DCHECK(!complete_);
    depfile_ = std::move(df);
  }

  const SubstitutionPattern& description() const { return description_; }
  void set_description(SubstitutionPattern desc) {
    DCHECK(!complete_);
    description_ = std::move(desc);
  }

  const SubstitutionList& outputs() const { return outputs_; }
  void set_outputs(SubstitutionList out) {
    DCHECK(!complete_);
    outputs_ = std::move(out);
  }

  const SubstitutionList& runtime_outputs() const { return runtime_outputs_; }
  void set_runtime_outputs(SubstitutionList run_out) {
    DCHECK(!complete_);
    runtime_outputs_ = std::move(run_out);
  }

  const std::string& output_prefix() const { return output_prefix_; }
  void set_output_prefix(std::string s) {
    DCHECK(!complete_);
    output_prefix_ = std::move(s);
  }

  bool restat() const { return restat_; }
  void set_restat(bool r) {
    DCHECK(!complete_);
    restat_ = r;
  }

  const SubstitutionPattern& rspfile() const { return rspfile_; }
  void set_rspfile(SubstitutionPattern rsp) {
    DCHECK(!complete_);
    rspfile_ = std::move(rsp);
  }

  const SubstitutionPattern& rspfile_content() const {
    return rspfile_content_;
  }
  void set_rspfile_content(SubstitutionPattern content) {
    DCHECK(!complete_);
    rspfile_content_ = std::move(content);
  }

  const LabelPtrPair<Pool>& pool() const { return pool_; }
  void set_pool(LabelPtrPair<Pool> pool) { pool_ = std::move(pool); }

  // Other functions ----------------------------------------------------------

  // Function for the above override to call to complete the tool.
  void SetToolComplete();

  // Substitutions required by this tool.
  const SubstitutionBits& substitution_bits() const {
    DCHECK(complete_);
    return substitution_bits_;
  }

  // Create a tool based on given features.
  static std::unique_ptr<Tool> CreateTool(const std::string& name);
  static std::unique_ptr<Tool> CreateTool(const ParseNode* function,
                                          const std::string& name,
                                          Scope* scope,
                                          Toolchain* toolchain,
                                          Err* err);

  static const char* GetToolTypeForSourceType(SourceFile::Type type);
  static const char* GetToolTypeForTargetFinalOutput(const Target* target);

 protected:
  explicit Tool(const char* t);

  // Initialization functions -------------------------------------------------
  //
  // Initialization methods used by InitTool(). If successful, will set the
  // field and return true, otherwise will return false. Must be called before
  // SetComplete().
  bool IsPatternInOutputList(const SubstitutionList& output_list,
                             const SubstitutionPattern& pattern) const;
  bool ValidateSubstitutionList(const std::vector<const Substitution*>& list,
                                const Value* origin,
                                Err* err) const;
  bool ValidateOutputs(Err* err) const;
  bool ReadBool(Scope* scope, const char* var, bool* field, Err* err);
  bool ReadString(Scope* scope, const char* var, std::string* field, Err* err);
  bool ReadPattern(Scope* scope,
                   const char* var,
                   SubstitutionPattern* field,
                   Err* err);
  bool ReadPatternList(Scope* scope,
                       const char* var,
                       SubstitutionList* field,
                       Err* err);
  bool ReadLabel(Scope* scope,
                 const char* var,
                 const Label& current_toolchain,
                 LabelPtrPair<Pool>* field,
                 Err* err);
  bool ReadOutputExtension(Scope* scope, Err* err);

  const ParseNode* defined_from_ = nullptr;
  const char* name_ = nullptr;

  SubstitutionPattern command_;
  std::string command_launcher_;
  std::string default_output_extension_;
  SubstitutionPattern default_output_dir_;
  SubstitutionPattern depfile_;
  SubstitutionPattern description_;
  SubstitutionList outputs_;
  SubstitutionList runtime_outputs_;
  std::string output_prefix_;
  bool restat_ = false;
  SubstitutionPattern rspfile_;
  SubstitutionPattern rspfile_content_;
  LabelPtrPair<Pool> pool_;

  bool complete_ = false;

  SubstitutionBits substitution_bits_;

  DISALLOW_COPY_AND_ASSIGN(Tool);
};

#endif  // TOOLS_GN_TOOL_H_
