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

class cmGlobalGenerator;
class cmMakefile;

/** \class cmExternalMakefileProjectGenerator
 * \brief Base class for generators for "External Makefile based IDE projects".
 *
 * cmExternalMakefileProjectGenerator is a base class for generators
 * for "external makefile based projects", i.e. IDE projects which work
 * an already existing makefiles.
 * See cmExtraEclipseCDT4Generator as an example.
 * After the makefiles have been generated by one of the Makefile
 * generators, the Generate() method is called and this generator
 * can iterate over the local generators and/or projects to produce the
 * project files for the IDE.
 */
class cmExternalMakefileProjectGenerator
{
public:
  virtual ~cmExternalMakefileProjectGenerator() = default;

  virtual void EnableLanguage(std::vector<std::string> const& languages,
                              cmMakefile*, bool optional);

  //! set the global generator which will generate the makefiles
  virtual void SetGlobalGenerator(cmGlobalGenerator* generator)
  {
    this->GlobalGenerator = generator;
  }

  //! Return the list of global generators supported by this extra generator
  std::vector<std::string> const& GetSupportedGlobalGenerators() const
  {
    return this->SupportedGlobalGenerators;
  }

  /** Create a full name from the given global generator name and the
   * extra generator name
   */
  static std::string CreateFullGeneratorName(
    std::string const& globalGenerator, std::string const& extraGenerator);

  //! Generate the project files, the Makefiles have already been generated
  virtual void Generate() = 0;

  void SetName(std::string const& n) { this->Name = n; }
  std::string GetName() const { return this->Name; }

  virtual bool Open(std::string const& bindir, std::string const& projectName,
                    bool dryRun);

protected:
  //! Contains the names of the global generators support by this generator.
  std::vector<std::string> SupportedGlobalGenerators;
  //! the global generator which creates the makefiles
  cmGlobalGenerator const* GlobalGenerator = nullptr;

  std::string Name;
};

class cmExternalMakefileProjectGeneratorFactory
{
public:
  cmExternalMakefileProjectGeneratorFactory(std::string n, std::string doc);
  virtual ~cmExternalMakefileProjectGeneratorFactory();

  std::string GetName() const;
  std::string GetDocumentation() const;
  std::vector<std::string> GetSupportedGlobalGenerators() const;
  std::vector<std::string> Aliases;

  virtual std::unique_ptr<cmExternalMakefileProjectGenerator>
  CreateExternalMakefileProjectGenerator() const = 0;

  void AddSupportedGlobalGenerator(std::string const& base);

private:
  std::string Name;
  std::string Documentation;
  std::vector<std::string> SupportedGlobalGenerators;
};

template <class T>
class cmExternalMakefileProjectGeneratorSimpleFactory
  : public cmExternalMakefileProjectGeneratorFactory
{
public:
  cmExternalMakefileProjectGeneratorSimpleFactory(std::string const& n,
                                                  std::string const& doc)
    : cmExternalMakefileProjectGeneratorFactory(n, doc)
  {
  }

  std::unique_ptr<cmExternalMakefileProjectGenerator>
  CreateExternalMakefileProjectGenerator() const override
  {
    std::unique_ptr<cmExternalMakefileProjectGenerator> p(new T);
    p->SetName(this->GetName());
    return p;
  }
};
