/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#ifndef cmCPackGenerator_h
#define cmCPackGenerator_h

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

#include <map>
#include <sstream>
#include <string>
#include <vector>

#include "cmCPackComponentGroup.h"
#include "cmSystemTools.h"
#include "cm_sys_stat.h"

class cmCPackLog;
class cmGlobalGenerator;
class cmInstalledFile;
class cmMakefile;

/** \class cmCPackGenerator
 * \brief A superclass of all CPack Generators
 *
 */
class cmCPackGenerator
{
public:
  virtual const char* GetNameOfClass() = 0;
  /**
   * If verbose then more information is printed out
   */
  void SetVerbose(bool val)
  {
    this->GeneratorVerbose =
      val ? cmSystemTools::OUTPUT_MERGE : cmSystemTools::OUTPUT_NONE;
  }

  /**
   * Put underlying cmake scripts in trace mode.
   */
  void SetTrace(bool val) { this->Trace = val; }

  /**
   * Put underlying cmake scripts in expanded trace mode.
   */
  void SetTraceExpand(bool val) { this->TraceExpand = val; }

  /**
   * Returns true if the generator may work on this system.
   * Rational:
   * Some CPack generator may run on some host and may not on others
   * (with the same system) because some tools are missing. If the tool
   * is missing then CPack won't activate (in the CPackGeneratorFactory)
   * this particular generator.
   */
  static bool CanGenerate() { return true; }

  /**
   * Do the actual whole package processing.
   * Subclass may redefine it but its usually enough
   * to redefine @ref PackageFiles, because in fact
   * this method do call:
   *     - PrepareName
   *     - clean-up temp dirs
   *     - InstallProject (with the appropriate method)
   *     - prepare list of files and/or components to be package
   *     - PackageFiles
   *     - Copy produced packages at the expected place
   * @return 0 if error.
   */
  virtual int DoPackage();

  /**
   * Initialize generator
   */
  int Initialize(const std::string& name, cmMakefile* mf);

  /**
   * Construct generator
   */
  cmCPackGenerator();
  virtual ~cmCPackGenerator();

  //! Set and get the options
  void SetOption(const std::string& op, const char* value);
  void SetOptionIfNotSet(const std::string& op, const char* value);
  const char* GetOption(const std::string& op) const;
  std::vector<std::string> GetOptions() const;
  bool IsSet(const std::string& name) const;
  bool IsOn(const std::string& name) const;
  bool IsSetToOff(const std::string& op) const;
  bool IsSetToEmpty(const std::string& op) const;

  //! Set the logger
  void SetLogger(cmCPackLog* log) { this->Logger = log; }

  //! Display verbose information via logger
  void DisplayVerboseOutput(const std::string& msg, float progress);

  bool ReadListFile(const char* moduleName);

protected:
  /**
   * Prepare common used names by inspecting
   * several CPACK_xxx var values.
   */
  int PrepareNames();

  /**
   * Install the project using appropriate method.
   */
  int InstallProject();

  int CleanTemporaryDirectory();

  cmInstalledFile const* GetInstalledFile(std::string const& name) const;

  virtual const char* GetOutputExtension() { return ".cpack"; }
  virtual const char* GetOutputPostfix() { return nullptr; }

  /**
   * Prepare requested grouping kind from CPACK_xxx vars
   * CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE
   * CPACK_COMPONENTS_IGNORE_GROUPS
   * or
   * CPACK_COMPONENTS_ONE_PACKAGE_PER_GROUP
   * @return 1 on success 0 on failure.
   */
  virtual int PrepareGroupingKind();

  /**
   * Some CPack generators may prefer to have
   * CPack install all components belonging to the same
   * [component] group to be install in the same directory.
   * The default behavior is to install each component in
   * a separate directory.
   * @param[in] componentName the name of the component to be installed
   * @return the name suffix the generator wants for the specified component
   *         default is "componentName"
   */
  virtual std::string GetComponentInstallDirNameSuffix(
    const std::string& componentName);

  /**
   * CPack specific generator may mangle CPACK_PACKAGE_FILE_NAME
   * with CPACK_COMPONENT_xxxx_<NAME>_DISPLAY_NAME if
   * CPACK_<GEN>_USE_DISPLAY_NAME_IN_FILENAME is ON.
   * @param[in] initialPackageFileName the initial package name to be mangled
   * @param[in] groupOrComponentName the name of the group/component
   * @param[in] isGroupName true if previous name refers to a group,
   *            false otherwise
   */
  virtual std::string GetComponentPackageFileName(
    const std::string& initialPackageFileName,
    const std::string& groupOrComponentName, bool isGroupName);

  /**
   * Package the list of files and/or components which
   * has been prepared by the beginning of DoPackage.
   * @pre the @ref toplevel has been filled-in
   * @pre the list of file @ref files has been populated
   * @pre packageFileNames contains at least 1 entry
   * @post packageFileNames may have been updated and contains
   *       the list of packages generated by the specific generator.
   */
  virtual int PackageFiles();
  virtual const char* GetInstallPath();
  virtual const char* GetPackagingInstallPrefix();

  virtual std::string FindTemplate(const char* name);
  virtual bool ConfigureFile(const char* inName, const char* outName,
                             bool copyOnly = false);
  virtual bool ConfigureString(const std::string& input, std::string& output);
  virtual int InitializeInternal();

  //! Run install commands if specified
  virtual int InstallProjectViaInstallCommands(
    bool setDestDir, const std::string& tempInstallDirectory);
  virtual int InstallProjectViaInstallScript(
    bool setDestDir, const std::string& tempInstallDirectory);
  virtual int InstallProjectViaInstalledDirectories(
    bool setDestDir, const std::string& tempInstallDirectory,
    const mode_t* default_dir_mode);
  virtual int InstallProjectViaInstallCMakeProjects(
    bool setDestDir, const std::string& tempInstallDirectory,
    const mode_t* default_dir_mode);

  virtual int RunPreinstallTarget(const std::string& installProjectName,
                                  const std::string& installDirectory,
                                  cmGlobalGenerator* globalGenerator,
                                  const std::string& buildConfig);
  virtual int InstallCMakeProject(
    bool setDestDir, const std::string& installDirectory,
    const std::string& baseTempInstallDirectory,
    const mode_t* default_dir_mode, const std::string& component,
    bool componentInstall, const std::string& installSubDirectory,
    const std::string& buildConfig, std::string& absoluteDestFiles);

  /**
   * The various level of support of
   * CPACK_SET_DESTDIR used by the generator.
   */
  enum CPackSetDestdirSupport
  {
    /* the generator works with or without it */
    SETDESTDIR_SUPPORTED,
    /* the generator works best if automatically handled */
    SETDESTDIR_INTERNALLY_SUPPORTED,
    /* no official support, use at your own risk */
    SETDESTDIR_SHOULD_NOT_BE_USED,
    /* officially NOT supported */
    SETDESTDIR_UNSUPPORTED
  };

  /**
   * Does the CPack generator support CPACK_SET_DESTDIR?
   * The default legacy value is 'SETDESTDIR_SUPPORTED' generator
   * have to override it in order change this.
   * @return CPackSetDestdirSupport
   */
  virtual enum CPackSetDestdirSupport SupportsSetDestdir() const;

  /**
   * Does the CPack generator support absolute path
   * in INSTALL DESTINATION?
   * The default legacy value is 'true' generator
   * have to override it in order change this.
   * @return true if supported false otherwise
   */
  virtual bool SupportsAbsoluteDestination() const;

  /**
   * Does the CPack generator support component installation?.
   * Some Generators requires the user to set
   * CPACK_<GENNAME>_COMPONENT_INSTALL in order to make this
   * method return true.
   * @return true if supported, false otherwise
   */
  virtual bool SupportsComponentInstallation() const;
  /**
   * Does the currently running generator want a component installation.
   * The generator may support component installation but he may
   * be requiring monolithic install using CPACK_MONOLITHIC_INSTALL.
   * @return true if component installation is supported and wanted.
   */
  virtual bool WantsComponentInstallation() const;
  virtual cmCPackInstallationType* GetInstallationType(
    const std::string& projectName, const std::string& name);
  virtual cmCPackComponent* GetComponent(const std::string& projectName,
                                         const std::string& name);
  virtual cmCPackComponentGroup* GetComponentGroup(
    const std::string& projectName, const std::string& name);

  cmSystemTools::OutputOption GeneratorVerbose;
  std::string Name;

  std::string InstallPath;

  /**
   * The list of package file names.
   * At beginning of DoPackage the (generic) generator will populate
   * the list of desired package file names then it will
   * call the redefined method PackageFiles which is may
   * either use this set of names (usually on entry there should be
   * only a single name) or update the vector with the list
   * of created package file names.
   */
  std::vector<std::string> packageFileNames;

  /**
   * The directory where all the files to be packaged reside.
   * If the installer support components there will be one
   * sub-directory for each component. In those directories
   * one will find the file belonging to the specified component.
   */
  std::string toplevel;

  /**
   * The complete list of files to be packaged.
   * This list will be populated by DoPackage before
   * PackageFiles is called.
   */
  std::vector<std::string> files;

  std::vector<cmCPackInstallCMakeProject> CMakeProjects;
  std::map<std::string, cmCPackInstallationType> InstallationTypes;
  /**
   * The set of components.
   * If component installation is supported then this map
   * contains the component specified in CPACK_COMPONENTS_ALL
   */
  std::map<std::string, cmCPackComponent> Components;
  std::map<std::string, cmCPackComponentGroup> ComponentGroups;

  /**
   * If components are enabled, this enum represents the different
   * ways of mapping components to package files.
   */
  enum ComponentPackageMethod
  {
    /* one package for all components */
    ONE_PACKAGE,
    /* one package for each component */
    ONE_PACKAGE_PER_COMPONENT,
    /* one package for each group,
     * with left over components in their own package */
    ONE_PACKAGE_PER_GROUP,
    UNKNOWN_COMPONENT_PACKAGE_METHOD
  };

  /**
   * The component package method
   * The default is ONE_PACKAGE_PER_GROUP,
   * and generators may override the default
   * before PrepareGroupingKind() is called.
   */
  ComponentPackageMethod componentPackageMethod;

  cmCPackLog* Logger;
  bool Trace;
  bool TraceExpand;

  cmMakefile* MakefileMap;
};

#define cmCPackTypeMacro(klass, superclass)                                   \
  typedef superclass Superclass;                                              \
  const char* GetNameOfClass() override { return #klass; }                    \
  static cmCPackGenerator* CreateGenerator() { return new klass; }            \
  class cmCPackTypeMacro_UseTrailingSemicolon

#define cmCPackLogger(logType, msg)                                           \
  do {                                                                        \
    std::ostringstream cmCPackLog_msg;                                        \
    cmCPackLog_msg << msg;                                                    \
    this->Logger->Log(logType, __FILE__, __LINE__,                            \
                      cmCPackLog_msg.str().c_str());                          \
  } while (false)

#endif
