// 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_NINJA_TARGET_WRITER_H_
#define TOOLS_GN_NINJA_TARGET_WRITER_H_

#include <iosfwd>

#include "gn/path_output.h"
#include "gn/resolved_target_data.h"
#include "gn/substitution_type.h"

class OutputFile;
class Settings;
class Target;
struct SubstitutionBits;

// Generates one target's ".ninja" file. The toplevel "build.ninja" file is
// generated by the NinjaBuildWriter.
class NinjaTargetWriter {
 public:
  NinjaTargetWriter(const Target* target, std::ostream& out);
  virtual ~NinjaTargetWriter();

  // Returns a ResolvedTargetData that can be used to retrieve information
  // from targets. The instance can be set through SetResolvedTargetData()
  // or may be created on demand otherwise (which is useful to keep unit-tests
  // simple).
  const ResolvedTargetData& resolved() const;

  // Sets the ResolvedTargetData instance to return for future resolved()
  // calls. Does not transfer ownership, and allows several NinjaTargetWriter
  // instances to share the same cached information.
  void SetResolvedTargetData(ResolvedTargetData* resolved);

  // Returns the build line to be written to the toolchain build file.
  //
  // Some targets have their rules written to separate files, and some can have
  // their rules coalesced in the main build file. For the coalesced case, this
  // function will return the rules as a string. For the separate file case,
  // the separate ninja file will be written and the return string will be the
  // subninja command to load that file.
  static std::string RunAndWriteFile(const Target* target,
                                     ResolvedTargetData* resolved = nullptr);

  virtual void Run() = 0;

 protected:
  // Returns a writable pointer to resolved(). Only used internally.
  ResolvedTargetData* GetResolvedTargetData();

  // Writes out the substitution values that are shared between the different
  // types of tools (target gen dir, target label, etc.). Only the substitutions
  // identified by the given bits will be written.
  void WriteSharedVars(const SubstitutionBits& bits);

  // Writes out the substitution values that are shared between C compiler tools
  // and action tools. Only the substitutions identified by the given bits will
  // be written.
  // If respect_source_used is set, the generated substitution values will
  // respect the types of source code used; otherwise they will respect the bits
  // passed in.
  void WriteCCompilerVars(const SubstitutionBits& bits,
                          bool indent,
                          bool respect_source_used);

  // Writes out the substitution values that are shared between Rust tools
  // and action tools. Only the substitutions identified by the given bits will
  // be written, unless 'always_write' is specified.
  void WriteRustCompilerVars(const SubstitutionBits& bits,
                             bool indent,
                             bool always_write);

  // Writes to the output stream a stamp rule for input dependencies, and
  // returns the file to be appended to source rules that encodes the
  // order-only dependencies for the current target.
  // If num_stamp_uses is small, this might return all input dependencies
  // directly, without writing a stamp file.
  // If there are no implicit dependencies and no additional target dependencies
  // are passed in, this returns an empty vector.
  std::vector<OutputFile> WriteInputDepsStampAndGetDep(
      const std::vector<const Target*>& additional_hard_deps,
      size_t num_stamp_uses) const;

  // Writes to the output file a final stamp rule for the target that stamps
  // the given list of files. This function assumes the stamp is for the target
  // as a whole so the stamp file is set as the target's dependency output.
  void WriteStampForTarget(const std::vector<OutputFile>& deps,
                           const std::vector<OutputFile>& order_only_deps);

  const Settings* settings_;  // Non-owning.
  const Target* target_;      // Non-owning.
  std::ostream& out_;
  PathOutput path_output_;

  // The ResolvedTargetData instance can be set through SetResolvedTargetData()
  // or it will be created lazily when resolved() is called, hence the need
  // for 'mutable' here.
  mutable ResolvedTargetData* resolved_ptr_ = nullptr;
  mutable std::unique_ptr<ResolvedTargetData> resolved_owned_;

 private:
  void WriteCopyRules();
  void WriteEscapedSubstitution(const Substitution* type);

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

#endif  // TOOLS_GN_NINJA_TARGET_WRITER_H_
