/* 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 <string>
#include <vector>

class cmCPackComponentGroup;

/** \class cmCPackInstallationType
 * \brief A certain type of installation, which encompasses a
 * set of components.
 */
class cmCPackInstallationType
{
public:
  /// The name of the installation type (used to reference this
  /// installation type).
  std::string Name;

  /// The name of the installation type as displayed to the user.
  std::string DisplayName;

  /// The index number of the installation type. This is an arbitrary
  /// numbering from 1 to the number of installation types.
  unsigned Index;
};

/** \class cmCPackComponent
 * \brief A single component to be installed by CPack.
 */
class cmCPackComponent
{
public:
  cmCPackComponent()
    : IsRequired(true)
    , IsHidden(false)
    , IsDisabledByDefault(false)
    , IsDownloaded(false)
  {
  }

  /// The name of the component (used to reference the component).
  std::string Name;

  /// The name of the component as displayed to the user.
  std::string DisplayName;

  /// The component group that contains this component (if any).
  cmCPackComponentGroup* Group = nullptr;

  /// Whether this component group must always be installed.
  bool IsRequired : 1;

  /// Whether this component group is hidden. A hidden component group
  /// is always installed. However, it may still be shown to the user.
  bool IsHidden : 1;

  /// Whether this component defaults to "disabled".
  bool IsDisabledByDefault : 1;

  /// Whether this component should be downloaded on-the-fly. If false,
  /// the component will be a part of the installation package.
  bool IsDownloaded : 1;

  /// A description of this component.
  std::string Description;

  /// The installation types that this component is a part of.
  std::vector<cmCPackInstallationType*> InstallationTypes;

  /// If IsDownloaded is true, the name of the archive file that
  /// contains the files that are part of this component.
  std::string ArchiveFile;

  /// The file to pass to --component-plist when using the
  /// productbuild generator.
  std::string Plist;

  /// The components that this component depends on.
  std::vector<cmCPackComponent*> Dependencies;

  /// The components that depend on this component.
  std::vector<cmCPackComponent*> ReverseDependencies;

  /// The list of installed files that are part of this component.
  std::vector<std::string> Files;

  /// The list of installed directories that are part of this component.
  std::vector<std::string> Directories;

  /// Get the total installed size of all of the files in this
  /// component, in bytes. installDir is the directory into which the
  /// component was installed.
  unsigned long GetInstalledSize(std::string const& installDir) const;

  /// Identical to GetInstalledSize, but returns the result in
  /// kilobytes.
  unsigned long GetInstalledSizeInKbytes(std::string const& installDir) const;

private:
  mutable unsigned long TotalSize = 0;
};

/** \class cmCPackComponentGroup
 * \brief A component group to be installed by CPack.
 */
class cmCPackComponentGroup
{
public:
  cmCPackComponentGroup()
    : IsBold(false)
    , IsExpandedByDefault(false)
  {
  }

  /// The name of the group (used to reference the group).
  std::string Name;

  /// The name of the component as displayed to the user.
  std::string DisplayName;

  /// The description of this component group.
  std::string Description;

  /// Whether the name of the component will be shown in bold.
  bool IsBold : 1;

  /// Whether the section should be expanded by default
  bool IsExpandedByDefault : 1;

  /// The components within this group.
  std::vector<cmCPackComponent*> Components;

  /// The parent group of this component group (if any).
  cmCPackComponentGroup* ParentGroup = nullptr;

  /// The subgroups of this group.
  std::vector<cmCPackComponentGroup*> Subgroups;
};

/** \class cmCPackInstallCMakeProject
 * \brief A single quadruplet from the CPACK_INSTALL_CMAKE_PROJECTS variable.
 */
class cmCPackInstallCMakeProject
{
public:
  /// The directory of the CMake project.
  std::string Directory;

  /// The name of the CMake project.
  std::string ProjectName;

  /// The name of the component (or component set) to install.
  std::string Component;

  /// The subdirectory to install into.
  std::string SubDirectory;

  /// The list of installation types.
  std::vector<cmCPackInstallationType*> InstallationTypes;

  /// The list of components.
  std::vector<cmCPackComponent*> Components;
};
