// Copyright (c) 2013 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_TARGET_H_
#define TOOLS_GN_TARGET_H_

#include <set>
#include <string>
#include <utility>
#include <vector>

#include "base/gtest_prod_util.h"
#include "base/logging.h"
#include "gn/action_values.h"
#include "gn/bundle_data.h"
#include "gn/config_values.h"
#include "gn/item.h"
#include "gn/label_pattern.h"
#include "gn/label_ptr.h"
#include "gn/metadata.h"
#include "gn/output_file.h"
#include "gn/pointer_set.h"
#include "gn/rust_values.h"
#include "gn/source_file.h"
#include "gn/swift_values.h"
#include "gn/toolchain.h"
#include "gn/unique_vector.h"

class DepsIteratorRange;
class Settings;
class Target;
class Toolchain;

using TargetSet = PointerSet<const Target>;

class Target : public Item {
 public:
  enum OutputType {
    UNKNOWN,
    GROUP,
    EXECUTABLE,
    SHARED_LIBRARY,
    LOADABLE_MODULE,
    STATIC_LIBRARY,
    SOURCE_SET,
    COPY_FILES,
    ACTION,
    ACTION_FOREACH,
    BUNDLE_DATA,
    CREATE_BUNDLE,
    GENERATED_FILE,
    RUST_LIBRARY,
    RUST_PROC_MACRO,
  };

  enum DepsIterationType {
    DEPS_ALL,     // Iterates through all public, private, and data deps.
    DEPS_LINKED,  // Iterates through all non-data dependencies.
  };

  using FileList = std::vector<SourceFile>;
  using StringVector = std::vector<std::string>;

  // We track the set of build files that may affect this target, please refer
  // to Scope for how this is determined.
  Target(const Settings* settings,
         const Label& label,
         const SourceFileSet& build_dependency_files = {});
  ~Target() override;

  // Returns a string naming the output type.
  static const char* GetStringForOutputType(OutputType type);

  // Item overrides.
  Target* AsTarget() override;
  const Target* AsTarget() const override;
  bool OnResolved(Err* err) override;

  OutputType output_type() const { return output_type_; }
  void set_output_type(OutputType t) { output_type_ = t; }

  // True for targets that compile source code (all types of libraries and
  // executables).
  bool IsBinary() const;

  // Can be linked into other targets.
  bool IsLinkable() const;

  // True if the target links dependencies rather than propagated up the graph.
  // This is also true of action and copy steps even though they don't link
  // dependencies, because they also don't propagate libraries up.
  bool IsFinal() const;

  // Set when the target should normally be treated as a data dependency. These
  // do not need to be treated as inputs or hard dependencies for normal build
  // steps, but have to be kept in the dependency tree to be properly
  // propagated. Treating these as data only decreases superfluous rebuilds and
  // increases parallelism.
  bool IsDataOnly() const;

  // Return true if this target should be generated in the final build graph.
  bool ShouldGenerate() const;

  // Will be the empty string to use the target label as the output name.
  // See GetComputedOutputName().
  const std::string& output_name() const { return output_name_; }
  void set_output_name(const std::string& name) { output_name_ = name; }

  // Returns the output name for this target, which is the output_name if
  // specified, or the target label if not.
  //
  // Because this depends on the tool for this target, the toolchain must
  // have been set before calling.
  std::string GetComputedOutputName() const;

  bool output_prefix_override() const { return output_prefix_override_; }
  void set_output_prefix_override(bool prefix_override) {
    output_prefix_override_ = prefix_override;
  }

  // Desired output directory for the final output. This will be used for
  // the {{output_dir}} substitution in the tool if it is specified. If
  // is_null, the tool default will be used.
  const SourceDir& output_dir() const { return output_dir_; }
  void set_output_dir(const SourceDir& dir) { output_dir_ = dir; }

  // The output extension is really a tri-state: unset (output_extension_set
  // is false and the string is empty, meaning the default extension should be
  // used), the output extension is set but empty (output should have no
  // extension) and the output extension is set but nonempty (use the given
  // extension).
  const std::string& output_extension() const { return output_extension_; }
  void set_output_extension(const std::string& extension) {
    output_extension_ = extension;
    output_extension_set_ = true;
  }
  bool output_extension_set() const { return output_extension_set_; }

  const FileList& sources() const { return sources_; }
  FileList& sources() { return sources_; }

  const SourceFileTypeSet& source_types_used() const {
    return source_types_used_;
  }
  SourceFileTypeSet& source_types_used() { return source_types_used_; }

  // Set to true when all sources are public. This is the default. In this case
  // the public headers list should be empty.
  bool all_headers_public() const { return all_headers_public_; }
  void set_all_headers_public(bool p) { all_headers_public_ = p; }

  // When all_headers_public is false, this is the list of public headers. It
  // could be empty which would mean no headers are public.
  const FileList& public_headers() const { return public_headers_; }
  FileList& public_headers() { return public_headers_; }

  // Whether this target's includes should be checked by "gn check".
  bool check_includes() const { return check_includes_; }
  void set_check_includes(bool ci) { check_includes_ = ci; }

  // Whether this static_library target should have code linked in.
  bool complete_static_lib() const { return complete_static_lib_; }
  void set_complete_static_lib(bool complete) {
    DCHECK_EQ(STATIC_LIBRARY, output_type_);
    complete_static_lib_ = complete;
  }

  // Metadata. Target takes ownership of the resulting scope.
  const Metadata& metadata() const;
  Metadata& metadata();
  bool has_metadata() const { return metadata_.get(); }

  // Get metadata from this target and its dependencies. This is intended to
  // be called after the target is resolved.
  bool GetMetadata(const std::vector<std::string>& keys_to_extract,
                   const std::vector<std::string>& keys_to_walk,
                   const SourceDir& rebase_dir,
                   bool deps_only,
                   std::vector<Value>* result,
                   TargetSet* targets_walked,
                   Err* err) const;

  // GeneratedFile-related methods.
  bool GenerateFile(Err* err) const;

  // Metadata collection methods for GeneratedFile targets.
  struct GeneratedFile {
    Value output_conversion_;
    Value contents_;  // Value::NONE if metadata collection should occur.
    SourceDir rebase_;
    std::vector<std::string> data_keys_;
    std::vector<std::string> walk_keys_;
  };
  const GeneratedFile& generated_file() const;
  GeneratedFile& generated_file();
  bool has_generated_file() const { return generated_file_.get(); }

  const Value& contents() const { return generated_file().contents_; }
  void set_contents(const Value& value) { generated_file().contents_ = value; }
  const Value& output_conversion() const {
    return generated_file().output_conversion_;
  }
  void set_output_conversion(const Value& value) {
    generated_file().output_conversion_ = value;
  }

  const SourceDir& rebase() const { return generated_file().rebase_; }
  void set_rebase(const SourceDir& value) { generated_file().rebase_ = value; }
  const std::vector<std::string>& data_keys() const {
    return generated_file().data_keys_;
  }
  std::vector<std::string>& data_keys() { return generated_file().data_keys_; }
  const std::vector<std::string>& walk_keys() const {
    return generated_file().walk_keys_;
  }
  std::vector<std::string>& walk_keys() { return generated_file().walk_keys_; }

  OutputFile write_runtime_deps_output() const {
    return write_runtime_deps_output_;
  }
  void set_write_runtime_deps_output(const OutputFile& value) {
    write_runtime_deps_output_ = value;
  }

  // Runtime dependencies. These are "file-like things" that can either be
  // directories or files. They do not need to exist, these are just passed as
  // runtime dependencies to external test systems as necessary.
  const std::vector<std::string>& data() const { return data_; }
  std::vector<std::string>& data() { return data_; }

  // Information about the bundle. Only valid for CREATE_BUNDLE target after
  // they have been resolved.
  const BundleData& bundle_data() const;
  BundleData& bundle_data();
  bool has_bundle_data() const { return bundle_data_.get(); }

  // Returns true if targets depending on this one should have an order
  // dependency.
  bool hard_dep() const {
    return output_type_ == ACTION || output_type_ == ACTION_FOREACH ||
           output_type_ == COPY_FILES || output_type_ == CREATE_BUNDLE ||
           output_type_ == BUNDLE_DATA || output_type_ == GENERATED_FILE ||
           builds_swift_module();
  }

  // Returns the iterator range which can be used in range-based for loops
  // to iterate over multiple types of deps in one loop:
  //   for (const auto& pair : target->GetDeps(Target::DEPS_ALL)) ...
  DepsIteratorRange GetDeps(DepsIterationType type) const;

  // Linked private dependencies.
  const LabelTargetVector& private_deps() const { return private_deps_; }
  LabelTargetVector& private_deps() { return private_deps_; }

  // Linked public dependencies.
  const LabelTargetVector& public_deps() const { return public_deps_; }
  LabelTargetVector& public_deps() { return public_deps_; }

  // Non-linked dependencies.
  const LabelTargetVector& data_deps() const { return data_deps_; }
  LabelTargetVector& data_deps() { return data_deps_; }

  // Validation dependencies.
  const LabelTargetVector& validations() const { return validations_; }
  LabelTargetVector& validations() { return validations_; }

  // gen_deps only propagate the "should_generate" flag. These dependencies can
  // have cycles so care should be taken if iterating over them recursively.
  const LabelTargetVector& gen_deps() const { return gen_deps_; }
  LabelTargetVector& gen_deps() { return gen_deps_; }

  // List of configs that this class inherits settings from. Once a target is
  // resolved, this will also list all-dependent and public configs.
  const UniqueVector<LabelConfigPair>& configs() const { return configs_; }
  UniqueVector<LabelConfigPair>& configs() { return configs_; }

  // List of configs that all dependencies (direct and indirect) of this
  // target get. These configs are not added to this target. Note that due
  // to the way this is computed, there may be duplicates in this list.
  const UniqueVector<LabelConfigPair>& all_dependent_configs() const {
    return all_dependent_configs_;
  }
  UniqueVector<LabelConfigPair>& all_dependent_configs() {
    return all_dependent_configs_;
  }

  // List of configs that targets depending directly on this one get. These
  // configs are also added to this target.
  const UniqueVector<LabelConfigPair>& public_configs() const {
    return public_configs_;
  }
  UniqueVector<LabelConfigPair>& public_configs() { return public_configs_; }

  // Dependencies that can include files from this target.
  const std::set<Label>& allow_circular_includes_from() const {
    return allow_circular_includes_from_;
  }
  std::set<Label>& allow_circular_includes_from() {
    return allow_circular_includes_from_;
  }

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

  // This config represents the configuration set directly on this target.
  ConfigValues& config_values();
  const ConfigValues& config_values() const;
  bool has_config_values() const { return config_values_.get(); }

  ActionValues& action_values();
  const ActionValues& action_values() const;
  bool has_action_values() const { return action_values_.get(); }

  SwiftValues& swift_values();
  const SwiftValues& swift_values() const;
  bool has_swift_values() const { return swift_values_.get(); }

  // Return true if this targets builds a SwiftModule
  bool builds_swift_module() const {
    return IsBinary() && source_types_used().SwiftSourceUsed();
  }

  RustValues& rust_values();
  const RustValues& rust_values() const;
  bool has_rust_values() const { return rust_values_.get(); }

  std::vector<LabelPattern>& friends() { return friends_; }
  const std::vector<LabelPattern>& friends() const { return friends_; }

  std::vector<LabelPattern>& assert_no_deps() { return assert_no_deps_; }
  const std::vector<LabelPattern>& assert_no_deps() const {
    return assert_no_deps_;
  }

  // The toolchain is only known once this target is resolved (all if its
  // dependencies are known). They will be null until then. Generally, this can
  // only be used during target writing.
  const Toolchain* toolchain() const { return toolchain_; }

  // Sets the toolchain. The toolchain must include a tool for this target
  // or the error will be set and the function will return false. Unusually,
  // this function's "err" output is optional since this is commonly used
  // frequently by unit tests which become needlessly verbose.
  bool SetToolchain(const Toolchain* toolchain, Err* err = nullptr);

  // Once this target has been resolved, all outputs from the target will be
  // listed here. This will include things listed in the "outputs" for an
  // action or a copy step, and the output library or executable file(s) from
  // binary targets.
  //
  // It will NOT include phony targets or object files.
  const std::vector<OutputFile>& computed_outputs() const {
    return computed_outputs_;
  }

  // Returns outputs from this target. The link output file is the one that
  // other targets link to when they depend on this target. This will only be
  // valid for libraries and will be empty for all other target types.
  //
  // The dependency output file is the file that should be used to express
  // a dependency on this one. It could be the same as the link output file
  // (this will be the case for static libraries). For shared libraries it
  // could be the same or different than the link output file, depending on the
  // system.
  //
  // The dependency output alias is only set when the target does not have an
  // output file and is using a Ninja phony target to represent it. The
  // exception to this is for phony targets without any real inputs. Ninja
  // treats empty phony targets as always dirty, so no other targets should
  // depend on that target. In that scenario, both dependency_output_alias or
  // dependency_output_file will be empty.
  //
  // Callers that do not care whether the dependency is represented by a file or
  // an alias should use dependency_output().
  //
  // These are only known once the target is resolved and will be empty before
  // that. This is a cache of the files to prevent every target that depends on
  // a given library from recomputing the same pattern.
  const OutputFile& link_output_file() const { return link_output_file_; }

  // Returns true if there is an output dependency file or phony alias.
  bool has_dependency_output() const {
    return has_dependency_output_file() || has_dependency_output_alias();
  }
  // Return the output dependency file path or phony alias if one is defined,
  // or an empty string otherwise.
  const OutputFile& dependency_output() const {
    return has_dependency_output_file() ? dependency_output_file_
                                        : dependency_output_alias_;
  }

  // Return true if there is a dependency file path defined for this target.
  bool has_dependency_output_file() const {
    return !dependency_output_file_.value().empty();
  }
  // Return the dependency output file path for this target if defined, or
  // an empty string otherwise.
  const OutputFile& dependency_output_file() const {
    return dependency_output_file_;
  }

  // Return true if there is a dependency output alias defined for this target.
  bool has_dependency_output_alias() const {
    return !dependency_output_alias_.value().empty();
  }
  // Return the dependency output alias if any, or an empty string otherwise.
  const OutputFile& dependency_output_alias() const {
    return dependency_output_alias_;
  }

  // The subset of computed_outputs that are considered runtime outputs.
  const std::vector<OutputFile>& runtime_outputs() const {
    return runtime_outputs_;
  }

  // The module name for the target.
  std::string module_name() const {
    return module_name_override_.empty() ? label().name()
                                         : module_name_override_;
  }
  void set_module_name(std::string module_name) {
    module_name_override_ = std::move(module_name);
  }

  // Computes and returns the outputs of this target expressed as SourceFiles.
  //
  // For binary target this depends on the tool for this target so the toolchain
  // must have been loaded beforehand. This will happen asynchronously so
  // calling this on a binary target before the build is complete will produce a
  // race condition.
  //
  // To resolve this, the caller passes in whether the entire build is complete
  // (this is used for the introspection commands which run after everything
  // else).
  //
  // If the build is complete, the toolchain will be used for binary targets to
  // compute the outputs. If the build is not complete, calling this function
  // for binary targets will produce an error.
  //
  // The |loc_for_error| is used to blame a location for any errors produced. It
  // can be empty if there is no range (like this is being called based on the
  // command-line.
  //
  // It is possible for |outputs| to be returned empty without an error being
  // reported. This can occur when the output type will result in a phony alias
  // target (like a source_set) that is omitted from build files when they have
  // no real inputs.
  bool GetOutputsAsSourceFiles(const LocationRange& loc_for_error,
                               bool build_complete,
                               std::vector<SourceFile>* outputs,
                               Err* err) const;

  // Computes the set of output files resulting from compiling the given source
  // file.
  //
  // For binary targets, if the file can be compiled and the tool exists, fills
  // the outputs in and writes the tool type to computed_tool_type. If the file
  // is not compilable, returns false.
  //
  // For action_foreach and copy targets, applies the output pattern to the
  // given file name to compute the outputs.
  //
  // For all other target types, just returns the target outputs because such
  // targets conceptually process all of their inputs as one step.
  //
  // The function can succeed with a "NONE" tool type for object files which
  // are just passed to the output. The output will always be overwritten, not
  // appended to.
  bool GetOutputFilesForSource(const SourceFile& source,
                               const char** computed_tool_type,
                               std::vector<OutputFile>* outputs) const;

 private:
  FRIEND_TEST_ALL_PREFIXES(TargetTest, ResolvePrecompiledHeaders);
  FRIEND_TEST_ALL_PREFIXES(TargetTest, HasRealInputs);

  // Pulls necessary information from dependencies to this one when all
  // dependencies have been resolved.
  void PullDependentTargetConfigs();
  void PullDependentTargetLibsFrom(const Target* dep, bool is_public);
  void PullDependentTargetLibs();
  void PullRecursiveHardDeps();
  void PullRecursiveBundleData();

  // Checks to see whether this target or any of its dependencies have real
  // inputs. If not, this target should be omitted as a dependency. This check
  // only applies to targets that will result in a phony rule.
  bool HasRealInputs() const;

  // Fills the link and dependency output files when a target is resolved.
  bool FillOutputFiles(Err* err);

  // Checks precompiled headers from configs and makes sure the resulting
  // values are in config_values_.
  bool ResolvePrecompiledHeaders(Err* err);

  // Validates the given thing when a target is resolved.
  bool CheckVisibility(Err* err) const;
  bool CheckConfigVisibility(Err* err) const;
  bool CheckTestonly(Err* err) const;
  bool CheckAssertNoDeps(Err* err) const;
  void CheckSourcesGenerated() const;
  bool CheckSourceSetLanguages(Err* err) const;

  OutputType output_type_ = UNKNOWN;
  std::string output_name_;
  bool output_prefix_override_ = false;
  SourceDir output_dir_;
  std::string output_extension_;
  bool output_extension_set_ = false;

  std::string module_name_override_;

  FileList sources_;
  SourceFileTypeSet source_types_used_;
  bool all_headers_public_ = true;
  FileList public_headers_;
  bool check_includes_ = true;
  bool complete_static_lib_ = false;
  std::vector<std::string> data_;
  std::unique_ptr<BundleData> bundle_data_;
  OutputFile write_runtime_deps_output_;

  LabelTargetVector private_deps_;
  LabelTargetVector public_deps_;
  LabelTargetVector data_deps_;
  LabelTargetVector validations_;
  LabelTargetVector gen_deps_;

  // See getters for more info.
  UniqueVector<LabelConfigPair> configs_;
  UniqueVector<LabelConfigPair> all_dependent_configs_;
  UniqueVector<LabelConfigPair> public_configs_;

  std::set<Label> allow_circular_includes_from_;

  LabelPtrPair<Pool> pool_;

  std::vector<LabelPattern> friends_;
  std::vector<LabelPattern> assert_no_deps_;

  // Used for all binary targets, and for inputs in regular targets. The
  // precompiled header values in this struct will be resolved to the ones to
  // use for this target, if precompiled headers are used.
  std::unique_ptr<ConfigValues> config_values_;

  // Used for action[_foreach] targets.
  std::unique_ptr<ActionValues> action_values_;

  // Used for Rust targets.
  std::unique_ptr<RustValues> rust_values_;

  // User for Swift targets.
  std::unique_ptr<SwiftValues> swift_values_;

  // Toolchain used by this target. Null until target is resolved.
  const Toolchain* toolchain_ = nullptr;

  // Output files. Empty until the target is resolved.
  std::vector<OutputFile> computed_outputs_;
  OutputFile link_output_file_;
  OutputFile dependency_output_file_;
  OutputFile dependency_output_alias_;
  std::vector<OutputFile> runtime_outputs_;

  std::unique_ptr<Metadata> metadata_;

  // GeneratedFile as metadata collection values.
  std::unique_ptr<GeneratedFile> generated_file_;

  Target(const Target&) = delete;
  Target& operator=(const Target&) = delete;
};

extern const char kExecution_Help[];

#endif  // TOOLS_GN_TARGET_H_
