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

#include "cmDiagnosticContext.h"
#include "cmInstallType.h"
#include "cmScriptGenerator.h"

class cmLocalGenerator;
class cmMakefile;
class cmListFileBacktrace;

/** \class cmInstallGenerator
 * \brief Support class for generating install scripts.
 *
 */
class cmInstallGenerator : public cmScriptGenerator
{
public:
  enum MessageLevel
  {
    MessageDefault,
    MessageAlways,
    MessageLazy,
    MessageNever
  };

  cmInstallGenerator(std::string destination,
                     std::vector<std::string> const& configurations,
                     std::string component, MessageLevel message,
                     bool excludeFromAll, bool allComponents,
                     cmDiagnosticContext context);
  ~cmInstallGenerator() override;

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

  virtual bool HaveInstall();
  virtual void CheckCMP0082(bool& haveSubdirectoryInstall,
                            bool& haveInstallAfterSubdirectory);

  void AddInstallRule(
    std::ostream& os, std::string const& dest, cmInstallType type,
    std::vector<std::string> const& files, bool optional = false,
    char const* permissionsFile = nullptr,
    char const* permissionsDir = nullptr, char const* rename = nullptr,
    char const* literalArgs = nullptr, Indent indent = Indent(),
    char const* filesVar = nullptr);

  /** Get the install destination as it should appear in the
      installation script.  */
  static std::string ConvertToAbsoluteDestination(std::string const& dest);
  void CheckAbsoluteDestination(std::string const& dest,
                                cmLocalGenerator* lg) const;

  /** Test if this generator installs something for a given configuration.  */
  bool InstallsForConfig(std::string const& config);

  /** Select message level from CMAKE_INSTALL_MESSAGE or 'never'.  */
  static MessageLevel SelectMessageLevel(cmMakefile* mf, bool never = false);

  /** Capture context for generator.  */
  static cmDiagnosticContext CaptureContext(cmMakefile const& mf);
  static cmDiagnosticContext CaptureContext(cmMakefile const* mf)
  {
    return cmInstallGenerator::CaptureContext(*mf);
  }

  virtual bool Compute(cmLocalGenerator*) { return true; }

  std::string const& GetComponent() const { return this->Component; }

  bool GetExcludeFromAll() const { return this->ExcludeFromAll; }
  bool GetAllComponentsFlag() const { return this->AllComponents; }

  cmListFileBacktrace const& GetBacktrace() const
  {
    return this->Context.GetBacktrace();
  }

  static std::string GetDestDirPath(std::string const& file);

protected:
  void GenerateScript(std::ostream& os) override;

  std::string CreateComponentTest(std::string const& component,
                                  bool excludeFromAll,
                                  bool allComponents = false);

  using TweakMethod =
    std::function<void(std::ostream& os, Indent indent,
                       std::string const& config, std::string const& file)>;
  static void AddTweak(std::ostream& os, Indent indent,
                       std::string const& config, std::string const& file,
                       TweakMethod const& tweak);
  static void AddTweak(std::ostream& os, Indent indent,
                       std::string const& config, std::string const& dir,
                       std::vector<std::string> const& files,
                       TweakMethod const& tweak);

  // Information shared by most generator types.
  std::string Destination;
  std::string const Component;
  MessageLevel const Message;
  bool const ExcludeFromAll;
  bool const AllComponents;
  cmDiagnosticContext const Context;
};
