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

#include "cmExportCMakeConfigGenerator.h"

class cmGeneratorTarget;
class cmGlobalGenerator;
class cmMakefile;

class cmExportTryCompileFileGenerator : public cmExportCMakeConfigGenerator
{
public:
  cmExportTryCompileFileGenerator(cmGlobalGenerator* gg,
                                  std::vector<std::string> const& targets,
                                  cmMakefile* mf,
                                  std::set<std::string> const& langs);

  /** Set the list of targets to export.  */
  void SetConfig(std::string const& config) { this->Config = config; }

protected:
  // Implement virtual methods from the superclass.
  void ComplainAboutDuplicateTarget(
    std::string const& /*targetName*/) const override {};
  void IssueMessage(MessageType type,
                    std::string const& message) const override;

  bool GenerateMainFile(std::ostream& os) override;

  void GenerateImportTargetsConfig(std::ostream&, std::string const&,
                                   std::string const&) override
  {
  }
  void HandleMissingTarget(std::string&, cmGeneratorTarget const*,
                           cmGeneratorTarget*) override
  {
  }

  ExportInfo FindExportInfo(cmGeneratorTarget const* /*target*/) const override
  {
    return { {}, {}, {} };
  }

  void PopulateProperties(cmGeneratorTarget const* target,
                          ImportPropertyMap& properties,
                          std::set<cmGeneratorTarget const*>& emitted);

  std::string InstallNameDir(cmGeneratorTarget const* target,
                             std::string const& config) override;

  std::string GetFileSetDirectories(cmGeneratorTarget* target,
                                    cmFileSet* fileSet,
                                    cmTargetExport const* te) override;

  std::string GetFileSetFiles(cmGeneratorTarget* target, cmFileSet* fileSet,
                              cmTargetExport const* te) override;

  std::string GetCxxModulesDirectory() const override { return {}; }
  void GenerateCxxModuleConfigInformation(std::string const&,
                                          std::ostream&) const override
  {
  }

private:
  std::string FindTargets(std::string const& prop,
                          cmGeneratorTarget const* tgt,
                          std::string const& language,
                          std::set<cmGeneratorTarget const*>& emitted);

  std::vector<cmGeneratorTarget const*> Exports;
  std::string Config;
  std::vector<std::string> Languages;
};
