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

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

#include "cmsys/FStream.hxx"

#include "cmCommonTargetGenerator.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalFastbuildGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmOSXBundleGenerator.h"

class cmCustomCommand;
class cmCustomCommandGenerator;
class cmLocalFastbuildGenerator;
class cmMakefile;
class cmSourceFile;

enum class FastbuildBuildStep
{
  PRE_BUILD,
  PRE_LINK,
  POST_BUILD,
  REST,
};

class cmFastbuildTargetGenerator : public cmCommonTargetGenerator
{
public:
  /// Create a cmFastbuildTargetGenerator according to the @a target's type and
  /// config.
  static cmFastbuildTargetGenerator* New(cmGeneratorTarget* target,
                                         std::string config);

  cmFastbuildTargetGenerator(cmGeneratorTarget* target, std::string config);

  virtual void Generate() {}

  std::string GetClangTidyReplacementsFilePath(
    std::string const& directory, cmSourceFile const& source,
    std::string const& Config) const override;

  void AddIncludeFlags(std::string& languageFlags, std::string const& language,
                       std::string const&) override;

  cmGeneratorTarget::Names DetectOutput() const;

  void AddObjectDependencies(FastbuildTarget& fastbuildTarget,
                             std::vector<std::string>& allObjectDepends) const;
  void AddLinkerNodeDependnecies(FastbuildTarget& fastbuildTarget);

  std::string ConvertToFastbuildPath(std::string const& path) const;

  cmGlobalFastbuildGenerator* GetGlobalGenerator() const;

  std::string GetName();

  cmMakefile* GetMakefile() const { return this->Makefile; }

  cmGeneratorTarget* GetGeneratorTarget() const
  {
    return this->GeneratorTarget;
  }

  void LogMessage(std::string const& m) const;

private:
  std::string GetUtilityAliasFromBuildStep(FastbuildBuildStep step) const;

protected:
  cmLocalFastbuildGenerator* GetLocalGenerator() const
  {
    return this->LocalGenerator;
  }

  std::string GetTargetName() const;
  std::string GetCdCommand(cmCustomCommandGenerator const& ccg) const;
  std::string GetScriptWorkingDir(cmCustomCommandGenerator const& ccg) const;
  std::string GetScriptFilename(std::string const& utilityTargetName) const;
  std::vector<std::string> GetDepends(
    cmCustomCommandGenerator const& ccg) const;

  void AddCommentPrinting(std::vector<std::string>& cmdLines,
                          cmCustomCommandGenerator const& ccg) const;

  void WriteCmdsToFile(cmsys::ofstream& file,
                       std::vector<std::string> const& cmds) const;

  void AddOutput(cmCustomCommandGenerator const& ccg, FastbuildExecNode& exec);

  void AddExecArguments(FastbuildExecNode& exec,
                        std::string const& scriptFilename) const;

  void ReplaceProblematicMakeVars(std::string& command) const;

  FastbuildExecNodes GenerateCommands(FastbuildBuildStep buildStep);
  FastbuildExecNode GetAppleTextStubCommand() const;
  FastbuildExecNode GetDepsCheckExec(FastbuildExecNode const& depender);

  std::string MakeCustomLauncher(cmCustomCommandGenerator const& ccg);

  std::string GetCustomCommandTargetName(cmCustomCommand const& cc,
                                         FastbuildBuildStep step) const;

  std::vector<std::string> GetInputFiles(cmCustomCommandGenerator const& ccg,
                                         FastbuildBuildStep step) const;

  void WriteScriptProlog(cmsys::ofstream& file) const;
  void WriteScriptEpilog(cmsys::ofstream& file) const;

  void AdditionalCleanFiles();

  // write rules for Mac OS X Application Bundle content.
  struct MacOSXContentGeneratorType
    : cmOSXBundleGenerator::MacOSXContentGeneratorType
  {
    MacOSXContentGeneratorType(cmFastbuildTargetGenerator* g, std::string cfg)
      : Generator(g)
      , Config(std::move(cfg))
    {
    }

    void operator()(cmSourceFile const& source, char const* pkgloc,
                    std::string const& config) override;

  private:
    cmFastbuildTargetGenerator* Generator;
    std::string const Config;
  };
  friend struct MacOSXContentGeneratorType;

  // "MacOSXContentGenerator" has to be per-config once multiconfig generator
  // is implemented.
  std::unique_ptr<MacOSXContentGeneratorType> MacOSXContentGenerator;
  std::unique_ptr<cmOSXBundleGenerator> OSXBundleGenerator;
  std::set<std::string> MacContentFolders;

  std::vector<FastbuildCopyNode> CopyNodes;

  cmLocalFastbuildGenerator* LocalGenerator;
  cmGlobalGenerator::TargetDependSet const TargetDirectDependencies;
  std::string const Config;

  // Sometimes CMake adds equivalent custom commands to different targets.
  // Not really supported by FBuild (can't have different exec nodes producing
  // same output). So, in such cases we need to "re-map" the exec to produce a
  // "dummy" output (and update all deps within the target).
  // TODO: potentially 1 map should be enough?
  std::unordered_map<std::string, std::string> OutputsToReplace;
  std::unordered_map<std::string, std::string> OutputToExecName;
};
