// 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_BUILD_WRITER_H_
#define TOOLS_GN_NINJA_BUILD_WRITER_H_

#include <iosfwd>
#include <map>
#include <string_view>
#include <unordered_map>
#include <vector>

#include "gn/path_output.h"

class Builder;
class BuildSettings;
class Err;
class Settings;
class Target;
class Toolchain;

namespace base {
class CommandLine;
}  // namespace base

// Generates the toplevel "build.ninja" file. This references the individual
// toolchain files and lists all input .gn files as dependencies of the
// build itself.
class NinjaBuildWriter {
 public:
  NinjaBuildWriter(const BuildSettings* settings,
                   const std::unordered_map<const Settings*, const Toolchain*>&
                       used_toolchains,
                   const std::vector<const Target*>& all_targets,
                   const Toolchain* default_toolchain,
                   const std::vector<const Target*>& default_toolchain_targets,
                   std::ostream& out,
                   std::ostream& dep_out);
  ~NinjaBuildWriter();

  // The design of this class is that this static factory function takes the
  // Builder, extracts the relevant information, and passes it to the class
  // constructor. The class itself doesn't depend on the Builder at all which
  // makes testing much easier (tests integrating various functions along with
  // the Builder get very complicated).
  static bool RunAndWriteFile(const BuildSettings* settings,
                              const Builder& builder,
                              Err* err);

  // Extracts from an existing build.ninja file's contents the commands
  // necessary to run GN and regenerate build.ninja.
  //
  // The regeneration rules live at the top of the build.ninja file and their
  // specific contents are an internal detail of NinjaBuildWriter. Used by
  // commands::PrepareForRegeneration.
  //
  // On error, returns an empty string.
  static std::string ExtractRegenerationCommands(
      const std::string& build_ninja_in);

  bool Run(Err* err);

 private:
  // WriteNinjaRules writes the rules that ninja uses to regenerate its own
  // build files, used whenever a build input file has changed.
  //
  // Ninja file regeneration is accomplished by two separate build statements.
  // This is necessary to work around ninja's behavior of deleting all output
  // files of a build edge if the edge uses a depfile and is interrupted before
  // it can complete. Previously, interrupting regeneration would cause ninja to
  // delete build.ninja, losing any flags/build settings passed to gen
  // previously and requiring the user to manually 'gen' again.
  //
  // The workaround involves misleading ninja about when the build.ninja file is
  // actually written. The first build statement runs the actual 'gen
  // --regeneration' command, writing "build.ninja" (and .d and .stamp) and
  // lists the "build.ninja.d" depfile to automatically trigger regeneration as
  // needed, but does not list "build.ninja" as an output. The second
  // statement's stated output is "build.ninja", but it simply uses the phony
  // rule to refer to the first statement.
  void WriteNinjaRules();
  void WriteAllPools();
  bool WriteSubninjas(Err* err);
  bool WritePhonyAndAllRules(Err* err);

  void WritePhonyRule(const Target* target, std::string_view phony_name);

  const BuildSettings* build_settings_;

  const std::unordered_map<const Settings*, const Toolchain*>& used_toolchains_;
  const std::vector<const Target*>& all_targets_;
  const Toolchain* default_toolchain_;
  const std::vector<const Target*>& default_toolchain_targets_;

  std::ostream& out_;
  std::ostream& dep_out_;
  PathOutput path_output_;

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

extern const char kNinjaRules_Help[];

// Exposed for testing.
base::CommandLine GetSelfInvocationCommandLine(
    const BuildSettings* build_settings);

#endif  // TOOLS_GN_NINJA_BUILD_WRITER_H_
