/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst or https://cmake.org/licensing for details.  */
#pragma once

#include "cmConfigure.h" // IWYU pragma: keep

#include <cstddef>
#include <iosfwd>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>

#include "cmBuildOptions.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalCommonGenerator.h"
#include "cmGlobalGeneratorFactory.h"
#include "cmStateSnapshot.h"

class cmGeneratedFileStream;
class cmLocalGenerator;
class cmLocalUnixMakefileGenerator3;
class cmMakefileTargetGenerator;
class cmake;

/** \class cmGlobalUnixMakefileGenerator3
 * \brief Write a Unix makefiles.
 *
 * cmGlobalUnixMakefileGenerator3 manages UNIX build process for a tree


 The basic approach of this generator is to produce Makefiles that will all
 be run with the current working directory set to the Home Output
 directory. The one exception to this is the subdirectory Makefiles which are
 created as a convenience and just cd up to the Home Output directory and
 invoke the main Makefiles.

 The make process starts with Makefile. Makefile should only contain the
 targets the user is likely to invoke directly from a make command line. No
 internal targets should be in this file. Makefile2 contains the internal
 targets that are required to make the process work.

 Makefile2 in turn will recursively make targets in the correct order. Each
 target has its own directory \<target\>.dir and its own makefile build.make in
 that directory. Also in that directory is a couple makefiles per source file
 used by the target. Typically these are named source.obj.build.make and
 source.obj.build.depend.make. The source.obj.build.make contains the rules
 for building, cleaning, and computing dependencies for the given source
 file. The build.depend.make contains additional dependencies that were
 computed during dependency scanning. An additional file called
 source.obj.depend is used as a marker to indicate when dependencies must be
 rescanned.

 Rules for custom commands follow the same model as rules for source files.

 */

class cmGlobalUnixMakefileGenerator3 : public cmGlobalCommonGenerator
{
public:
  cmGlobalUnixMakefileGenerator3(cmake* cm);
  static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
  {
    return std::unique_ptr<cmGlobalGeneratorFactory>(
      new cmGlobalGeneratorSimpleFactory<cmGlobalUnixMakefileGenerator3>());
  }

  ~cmGlobalUnixMakefileGenerator3() override;

  cmGlobalUnixMakefileGenerator3(cmGlobalUnixMakefileGenerator3 const&) =
    delete;
  cmGlobalUnixMakefileGenerator3& operator=(
    cmGlobalUnixMakefileGenerator3 const&) = delete;

  //! Get the name for the generator.
  std::string GetName() const override
  {
    return cmGlobalUnixMakefileGenerator3::GetActualName();
  }
  static std::string GetActualName() { return "Unix Makefiles"; }

  /**
   * Utilized by the generator factory to determine if this generator
   * supports toolsets.
   */
  static bool SupportsToolset() { return false; }

  /**
   * Utilized by the generator factory to determine if this generator
   * supports platforms.
   */
  static bool SupportsPlatform() { return false; }

  /**
   * Utilized to determine if this generator
   * supports DEPFILE option.
   */
  bool SupportsCustomCommandDepfile() const override { return true; }

  /**
   * Utilized to determine if this generator
   * supports linker dependency file.
   */
  bool SupportsLinkerDependencyFile() const override { return true; }

  /** Get the documentation entry for this generator.  */
  static cmDocumentationEntry GetDocumentation();

  std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
    cmMakefile* mf) override;

  /**
   * Try to determine system information such as shared library
   * extension, pthreads, byte order etc.
   */
  void EnableLanguage(std::vector<std::string> const& languages, cmMakefile*,
                      bool optional) override;

  void Configure() override;

  bool IsGNUMakeJobServerAware() const override { return true; }

  /**
   * Generate the all required files for building this project/tree. This
   * basically creates a series of LocalGenerators for each directory and
   * requests that they Generate.
   */
  void Generate() override;

  void WriteMainCMakefileLanguageRules(
    cmGeneratedFileStream& cmakefileStream,
    std::vector<std::unique_ptr<cmLocalGenerator>>&);

  // write out the help rule listing the valid targets
  void WriteHelpRule(std::ostream& ruleFileStream,
                     cmLocalUnixMakefileGenerator3*);

  // write the top level target rules
  void WriteConvenienceRules(std::ostream& ruleFileStream,
                             std::set<std::string>& emitted);

  // Make tool supports dependency files generated by compiler
  bool SupportsCompilerDependencies() const
  {
    return this->ToolSupportsCompilerDependencies;
  }

  // Make tool supports long line dependencies
  bool SupportsLongLineDependencies() const
  {
    return this->ToolSupportsLongLineDependencies;
  }

  /** Get the command to use for a target that has no rule.  This is
      used for multiple output dependencies and for cmake_force.  */
  std::string GetEmptyRuleHackCommand() { return this->EmptyRuleHackCommand; }

  /** Get the fake dependency to use when a rule has no real commands
      or dependencies.  */
  std::string GetEmptyRuleHackDepends() { return this->EmptyRuleHackDepends; }

  /**
   * Convert a file path to a Makefile target or dependency with
   * escaping and quoting suitable for the generator's make tool.
   */
  std::string ConvertToMakefilePath(std::string const& path) const;

  // change the build command for speed
  std::vector<GeneratedMakeCommand> GenerateBuildCommand(
    std::string const& makeProgram, std::string const& projectName,
    std::string const& projectDir, std::vector<std::string> const& targetNames,
    std::string const& config, int jobs, bool verbose,
    cmBuildOptions buildOptions = cmBuildOptions(),
    std::vector<std::string> const& makeOptions = std::vector<std::string>(),
    BuildTryCompile isInTryCompile = BuildTryCompile::No) override;

  /** Record per-target progress information.  */
  void RecordTargetProgress(cmMakefileTargetGenerator* tg);

  void AddCXXCompileCommand(std::string const& sourceFile,
                            std::string const& workingDirectory,
                            std::string const& compileCommand,
                            std::string const& objPath);

  /** Does the make tool tolerate .NOTPARALLEL? */
  virtual bool AllowNotParallel() const { return true; }

  /** Does the make tool tolerate .DELETE_ON_ERROR? */
  virtual bool AllowDeleteOnError() const { return true; }

  /** Does the make tool interpret '\#' as '#'?  */
  virtual bool CanEscapeOctothorpe() const;

  bool IsIPOSupported() const override { return true; }

  bool SupportsShortObjectNames() const override;
  void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;

  std::string IncludeDirective;
  std::string LineContinueDirective;
  bool DefineWindowsNULL;
  bool PassMakeflags;
  bool UnixCD;

protected:
  void WriteMainMakefile2();
  void WriteMainCMakefile();

  void WriteConvenienceRules2(std::ostream& ruleFileStream,
                              cmLocalUnixMakefileGenerator3& rootLG,
                              cmLocalUnixMakefileGenerator3& lg);

  void WriteDirectoryRule2(std::ostream& ruleFileStream,
                           cmLocalUnixMakefileGenerator3& rootLG,
                           DirectoryTarget const& dt, char const* pass,
                           bool check_all, bool check_relink,
                           std::vector<std::string> const& commands = {});
  void WriteDirectoryRules2(std::ostream& ruleFileStream,
                            cmLocalUnixMakefileGenerator3& rootLG,
                            DirectoryTarget const& dt);

  void AppendGlobalTargetDepends(std::vector<std::string>& depends,
                                 cmGeneratorTarget* target);

  void AppendCodegenTargetDepends(std::vector<std::string>& depends,
                                  cmGeneratorTarget* target);

  // Target name hooks for superclass.
  char const* GetAllTargetName() const override { return "all"; }
  char const* GetInstallTargetName() const override { return "install"; }
  char const* GetInstallLocalTargetName() const override
  {
    return "install/local";
  }
  char const* GetInstallStripTargetName() const override
  {
    return "install/strip";
  }
  char const* GetPreinstallTargetName() const override { return "preinstall"; }
  char const* GetTestTargetName() const override { return "test"; }
  char const* GetPackageTargetName() const override { return "package"; }
  char const* GetPackageSourceTargetName() const override
  {
    return "package_source";
  }
  char const* GetRebuildCacheTargetName() const override
  {
    return "rebuild_cache";
  }
  char const* GetCleanTargetName() const override { return "clean"; }

  bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const override { return true; }

  // Specify if the make tool is able to consume dependency files
  // generated by the compiler
  bool ToolSupportsCompilerDependencies = true;

  // some Make generator, such as Borland not support long line dependencies,
  // we add SupportsLongLineDependencies to predicate.
  bool ToolSupportsLongLineDependencies = true;

  // Some make programs (Borland) do not keep a rule if there are no
  // dependencies or commands.  This is a problem for creating rules
  // that might not do anything but might have other dependencies
  // added later.  If non-empty this variable holds a fake dependency
  // that can be added.
  std::string EmptyRuleHackDepends;

  // Some make programs (Watcom) do not like rules with no commands.
  // If non-empty this variable holds a bogus command that may be put
  // in the rule to satisfy the make program.
  std::string EmptyRuleHackCommand;

  // Store per-target progress counters.
  struct TargetProgress
  {
    unsigned long NumberOfActions = 0;
    std::string VariableFile;
    std::vector<unsigned long> Marks;
    void WriteProgressVariables(unsigned long total, unsigned long& current);
  };
  using ProgressMapType = std::map<cmGeneratorTarget const*, TargetProgress,
                                   cmGeneratorTarget::StrictTargetComparison>;
  ProgressMapType ProgressMap;

  size_t CountProgressMarksInTarget(
    cmGeneratorTarget const* target,
    std::set<cmGeneratorTarget const*>& emitted);
  size_t CountProgressMarksInAll(cmLocalGenerator const& lg);

  std::unique_ptr<cmGeneratedFileStream> CommandDatabase;

private:
  char const* GetBuildIgnoreErrorsFlag() const override { return "-i"; }

  std::map<cmStateSnapshot, std::set<cmGeneratorTarget const*>,
           cmStateSnapshot::StrictWeakOrder>
    DirectoryTargetsMap;
  void InitializeProgressMarks() override;
};
