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

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

#include <cm/optional>
#include <cm/string_view>

#include "cmGlobalVisualStudio8Generator.h"

class cmGeneratorTarget;
class cmLocalGenerator;
class cmMakefile;
class cmSourceFile;
class cmake;
struct cmIDEFlagTable;

/** \class cmGlobalVisualStudio10Generator
 * \brief Write a Unix makefiles.
 *
 * cmGlobalVisualStudio10Generator manages UNIX build process for a tree
 */
class cmGlobalVisualStudio10Generator : public cmGlobalVisualStudio8Generator
{
public:
  bool IsVisualStudioAtLeast10() const override { return true; }

  bool SetSystemName(std::string const& s, cmMakefile* mf) override;
  bool SetGeneratorToolset(std::string const& ts, bool build,
                           cmMakefile* mf) override;

  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;

  //! create the correct local generator
  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 AddAndroidExecutableWarning(std::string const& name)
  {
    this->AndroidExecutableWarnings.insert(name);
  }

  bool IsCudaEnabled() const { return this->CudaEnabled; }

  /** Generating for Nsight Tegra VS plugin?  */
  bool IsNsightTegra() const;
  std::string GetNsightTegraVersion() const;

  /** The vctargets path for the target platform.  */
  char const* GetCustomVCTargetsPath() const;

  /** The toolset name for the target platform.  */
  char const* GetPlatformToolset() const;
  std::string const& GetPlatformToolsetString() const;

  /** Return true when using a Visual Studio clang-cl toolset.  */
  bool IsClangClToolset() const override;

  /** The toolset version props file, if any.  */
  std::string const& GetPlatformToolsetVersionProps() const;

  /** The toolset host architecture name (e.g. x64 for 64-bit host tools).  */
  char const* GetPlatformToolsetHostArchitecture() const;
  std::string const& GetPlatformToolsetHostArchitectureString() const;

  /** The cuda toolset version.  */
  char const* GetPlatformToolsetCuda() const;
  std::string const& GetPlatformToolsetCudaString() const;

  /** The custom cuda install directory */
  char const* GetPlatformToolsetCudaCustomDir() const;
  std::string const& GetPlatformToolsetCudaCustomDirString() const;

  /** The nvcc subdirectory of a custom cuda install directory */
  std::string const& GetPlatformToolsetCudaNvccSubdirString() const;

  /** The visual studio integration subdirectory of a custom cuda install
   * directory */
  std::string const& GetPlatformToolsetCudaVSIntegrationSubdirString() const;

  /** The fortran toolset name.  */
  cm::optional<std::string> GetPlatformToolsetFortran() const override;

  /** Return whether we need to use No/Debug instead of false/true
      for GenerateDebugInformation.  */
  bool GetPlatformToolsetNeedsDebugEnum() const
  {
    return this->PlatformToolsetNeedsDebugEnum;
  }

  /** Return the CMAKE_SYSTEM_NAME.  */
  std::string const& GetSystemName() const { return this->SystemName; }

  /** Return the CMAKE_SYSTEM_VERSION.  */
  std::string const& GetSystemVersion() const { return this->SystemVersion; }

  /** Return the Windows version targeted on VS 2015 and above.  */
  std::string const& GetWindowsTargetPlatformVersion() const
  {
    return this->WindowsTargetPlatformVersion;
  }

  /** Return true if building for WindowsCE */
  bool TargetsWindowsCE() const override { return this->SystemIsWindowsCE; }

  /** Return true if building for WindowsPhone */
  bool TargetsWindowsPhone() const { return this->SystemIsWindowsPhone; }

  /** Return true if building for WindowsStore */
  bool TargetsWindowsStore() const { return this->SystemIsWindowsStore; }

  /** Return true if building for WindowsKernelModeDriver */
  bool TargetsWindowsKernelModeDriver() const
  {
    return this->SystemIsWindowsKernelModeDriver;
  }

  /** Return true if building for Android */
  bool TargetsAndroid() const { return this->SystemIsAndroid; }

  char const* GetCMakeCFGIntDir() const override { return "$(Configuration)"; }

  /** Generate an <output>.rule file path for a given command output.  */
  std::string GenerateRuleFile(std::string const& output) const override;

  void PathTooLong(cmGeneratorTarget* target, cmSourceFile const* sf,
                   std::string const& sfRel);

  std::string Encoding() override;
  char const* GetToolsVersion() const;

  virtual cm::optional<std::string> GetVSInstanceVersion() const { return {}; }

  bool GetSupportsUnityBuilds() const { return this->SupportsUnityBuilds; }

  virtual cm::optional<std::string> FindMSBuildCommandEarly(cmMakefile* mf);

  bool FindMakeProgram(cmMakefile* mf) override;

  bool IsIPOSupported() const override { return true; }

  virtual bool IsStdOutEncodingSupported() const { return false; }

  virtual bool IsUtf8EncodingSupported() const { return false; }

  virtual bool IsScanDependenciesSupported() const { return false; }

  static std::string GetInstalledNsightTegraVersion();

  /** Return the first two components of CMAKE_SYSTEM_VERSION.  */
  std::string GetApplicationTypeRevision() const;

  virtual char const* GetAndroidApplicationTypeRevision() const { return ""; }

  cmIDEFlagTable const* GetClFlagTable() const;
  cmIDEFlagTable const* GetCSharpFlagTable() const;
  cmIDEFlagTable const* GetRcFlagTable() const;
  cmIDEFlagTable const* GetLibFlagTable() const;
  cmIDEFlagTable const* GetLinkFlagTable() const;
  cmIDEFlagTable const* GetCudaFlagTable() const;
  cmIDEFlagTable const* GetCudaHostFlagTable() const;
  cmIDEFlagTable const* GetMarmasmFlagTable() const;
  cmIDEFlagTable const* GetMasmFlagTable() const;
  cmIDEFlagTable const* GetNasmFlagTable() const;

  bool IsMsBuildRestoreSupported() const;
  bool IsBuildInParallelSupported() const;

  bool SupportsShortObjectNames() const override;

protected:
  cmGlobalVisualStudio10Generator(cmake* cm, std::string const& name);

  void Generate() override;
  virtual bool InitializeSystem(cmMakefile* mf);
  virtual bool InitializeWindows(cmMakefile* mf);
  virtual bool InitializeWindowsCE(cmMakefile* mf);
  virtual bool InitializeWindowsPhone(cmMakefile* mf);
  virtual bool InitializeWindowsStore(cmMakefile* mf);
  virtual bool InitializeWindowsKernelModeDriver(cmMakefile* mf);
  virtual bool InitializeTegraAndroid(cmMakefile* mf);
  virtual bool InitializeAndroid(cmMakefile* mf);

  bool InitializePlatform(cmMakefile* mf) override;
  virtual bool InitializePlatformWindows(cmMakefile* mf);
  virtual bool VerifyNoGeneratorPlatformVersion(cmMakefile* mf) const;

  virtual bool ProcessGeneratorToolsetField(std::string const& key,
                                            std::string const& value);

  virtual std::string SelectWindowsCEToolset() const;
  virtual bool SelectWindowsPhoneToolset(std::string& toolset) const;
  virtual bool SelectWindowsStoreToolset(std::string& toolset) const;

  enum class AuxToolset
  {
    None,
    Default,
    PropsExist,
    PropsMissing,
    PropsIndeterminate
  };
  virtual AuxToolset FindAuxToolset(std::string& version,
                                    std::string& props) const;

  std::string const& GetMSBuildCommand();

  cmIDEFlagTable const* LoadFlagTable(std::string const& toolSpecificName,
                                      std::string const& defaultName,
                                      std::string const& table) const;

  std::string GeneratorToolset;
  std::string GeneratorToolsetVersionProps;
  std::string GeneratorToolsetHostArchitecture;
  std::string GeneratorToolsetCustomVCTargetsDir;
  std::string GeneratorToolsetCuda;
  std::string GeneratorToolsetCudaCustomDir;
  std::string GeneratorToolsetCudaNvccSubdir;
  std::string GeneratorToolsetCudaVSIntegrationSubdir;
  cm::optional<std::string> GeneratorToolsetFortran;
  cm::optional<std::string> DefaultToolsetFortran;
  std::string DefaultPlatformToolset;
  std::string DefaultPlatformToolsetHostArchitecture;
  std::string DefaultAndroidToolset;
  std::string WindowsTargetPlatformVersion;
  std::string SystemName;
  std::string SystemVersion;
  std::string NsightTegraVersion;
  std::string DefaultCLFlagTableName;
  std::string DefaultCSharpFlagTableName;
  std::string DefaultLibFlagTableName;
  std::string DefaultLinkFlagTableName;
  std::string DefaultCudaFlagTableName;
  std::string DefaultCudaHostFlagTableName;
  std::string DefaultMarmasmFlagTableName;
  std::string DefaultMasmFlagTableName;
  std::string DefaultNasmFlagTableName;
  std::string DefaultRCFlagTableName;
  bool SupportsUnityBuilds = false;
  bool SystemIsWindowsCE = false;
  bool SystemIsWindowsPhone = false;
  bool SystemIsWindowsStore = false;
  bool SystemIsWindowsKernelModeDriver = false;
  bool SystemIsAndroid = false;
  bool MSBuildCommandInitialized = false;

private:
  struct LongestSourcePath
  {
    LongestSourcePath() = default;
    size_t Length = 0;
    cmGeneratorTarget* Target = nullptr;
    cmSourceFile const* SourceFile = nullptr;
    std::string SourceRel;
  };
  LongestSourcePath LongestSource;

  std::string MSBuildCommand;
  std::set<std::string> AndroidExecutableWarnings;
  virtual std::string FindMSBuildCommand();
  std::string GetVSMakeProgram() override { return this->GetMSBuildCommand(); }

  std::string GeneratorToolsetVersion;

  bool PlatformToolsetNeedsDebugEnum = false;

  bool ParseGeneratorToolset(std::string const& ts, cmMakefile* mf);

  std::string GetClFlagTableName() const;
  std::string GetCSharpFlagTableName() const;
  std::string GetRcFlagTableName() const;
  std::string GetLibFlagTableName() const;
  std::string GetLinkFlagTableName() const;
  std::string GetMasmFlagTableName() const;
  std::string CanonicalToolsetName(std::string const& toolset) const;

  cm::optional<std::string> FindFlagTable(cm::string_view toolsetName,
                                          cm::string_view table) const;

  std::string CustomFlagTableDir;

  std::string CustomVCTargetsPath;
  std::string VCTargetsPath;
  bool FindVCTargetsPath(cmMakefile* mf);

  bool CudaEnabled = false;

  // We do not use the reload macros for VS >= 10.
  std::string GetUserMacrosDirectory() override { return ""; }
};
