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

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

#include <iosfwd>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "cmsys/RegularExpression.hxx"

#include "cmComputeLinkDepends.h"
#include "cmListFileCache.h"
#include "cmValue.h"

class cmGeneratorTarget;
class cmGlobalGenerator;
class cmMakefile;
class cmOrderDirectories;
class cmSourceFile;
class cmake;

/** \class cmComputeLinkInformation
 * \brief Compute link information for a target in one configuration.
 */
class cmComputeLinkInformation
{
private:
  class FeatureDescriptor;

public:
  cmComputeLinkInformation(cmGeneratorTarget const* target,
                           const std::string& config);
  cmComputeLinkInformation(const cmComputeLinkInformation&) = delete;
  cmComputeLinkInformation& operator=(const cmComputeLinkInformation&) =
    delete;
  ~cmComputeLinkInformation();
  bool Compute();

  enum class ItemIsPath
  {
    No,
    Yes,
  };

  struct Item
  {
    Item(BT<std::string> v, ItemIsPath isPath,
         cmGeneratorTarget const* target = nullptr,
         cmSourceFile const* objectSource = nullptr,
         FeatureDescriptor const* feature = nullptr)
      : Value(std::move(v))
      , IsPath(isPath)
      , Target(target)
      , ObjectSource(objectSource)
      , Feature(feature)
    {
    }
    BT<std::string> Value;
    ItemIsPath IsPath = ItemIsPath::No;
    cmGeneratorTarget const* Target = nullptr;
    // The source file representing the external object (used when linking
    // `$<TARGET_OBJECTS>`)
    cmSourceFile const* ObjectSource = nullptr;

    bool HasFeature() const { return this->Feature != nullptr; }
    const std::string& GetFeatureName() const
    {
      return HasFeature() ? this->Feature->Name
                          : cmComputeLinkDepends::LinkEntry::DEFAULT;
    }

    BT<std::string> GetFormattedItem(std::string const& path) const
    {
      return { this->Feature
                 ? this->Feature->GetDecoratedItem(path, this->IsPath)
                 : path,
               Value.Backtrace };
    }

  private:
    FeatureDescriptor const* Feature = nullptr;
  };
  using ItemVector = std::vector<Item>;
  void AppendValues(std::string& result, std::vector<BT<std::string>>& values);
  ItemVector const& GetItems() const;
  std::vector<std::string> const& GetDirectories() const;
  std::vector<BT<std::string>> GetDirectoriesWithBacktraces();
  std::vector<std::string> const& GetDepends() const;
  std::vector<std::string> const& GetFrameworkPaths() const;
  std::set<std::string> const& GetFrameworkPathsEmitted() const;
  std::vector<std::string> const& GetXcFrameworkHeaderPaths() const;
  std::string GetLinkLanguage() const { return this->LinkLanguage; }
  std::vector<std::string> const& GetRuntimeSearchPath() const;
  std::string const& GetRuntimeFlag() const { return this->RuntimeFlag; }
  std::string const& GetRuntimeSep() const { return this->RuntimeSep; }
  void GetRPath(std::vector<std::string>& runtimeDirs, bool for_install) const;
  std::string GetRPathString(bool for_install) const;
  std::string GetChrpathString() const;
  std::set<cmGeneratorTarget const*> const& GetSharedLibrariesLinked() const;
  std::vector<cmGeneratorTarget const*> const& GetExternalObjectTargets()
    const;
  std::vector<cmGeneratorTarget const*> const& GetRuntimeDLLs() const
  {
    return this->RuntimeDLLs;
  }

  std::string const& GetLibLinkFileFlag() const
  {
    return this->LibLinkFileFlag;
  }

  std::string const& GetObjLinkFileFlag() const
  {
    return this->ObjLinkFileFlag;
  }

  std::string const& GetRPathLinkFlag() const { return this->RPathLinkFlag; }
  std::string GetRPathLinkString() const;

  std::string GetConfig() const { return this->Config; }

  const cmGeneratorTarget* GetTarget() { return this->Target; }

private:
  using LinkEntry = cmComputeLinkDepends::LinkEntry;

  void AddItem(LinkEntry const& entry);
  void AddSharedDepItem(LinkEntry const& entry);
  void AddRuntimeDLL(cmGeneratorTarget const* tgt);

  // Output information.
  ItemVector Items;
  std::vector<std::string> Directories;
  std::vector<std::string> Depends;
  std::vector<std::string> FrameworkPaths;
  std::vector<std::string> XcFrameworkHeaderPaths;
  std::vector<std::string> RuntimeSearchPath;
  std::set<cmGeneratorTarget const*> SharedLibrariesLinked;
  std::vector<cmGeneratorTarget const*> ExternalObjectTargets;
  std::vector<cmGeneratorTarget const*> RuntimeDLLs;

  // Context information.
  cmGeneratorTarget const* const Target;
  cmMakefile* const Makefile;
  cmGlobalGenerator* const GlobalGenerator;
  cmake* const CMakeInstance;

  // Configuration information.
  std::string const Config;
  std::string LinkLanguage;

  // Modes for dealing with dependent shared libraries.
  enum SharedDepMode
  {
    SharedDepModeNone,   // Drop
    SharedDepModeDir,    // List dir in -rpath-link flag
    SharedDepModeLibDir, // List dir in linker search path
    SharedDepModeLink    // List file on link line
  };

  cmValue LoaderFlag;
  std::string LibLinkFlag;
  std::string LibLinkFileFlag;
  std::string ObjLinkFileFlag;
  std::string LibLinkSuffix;
  std::string RuntimeFlag;
  std::string RuntimeSep;
  std::string RuntimeAlways;
  std::string RPathLinkFlag;
  SharedDepMode SharedDependencyMode;

  enum LinkType
  {
    LinkUnknown,
    LinkStatic,
    LinkShared
  };
  void SetCurrentLinkType(LinkType lt);

  // Link type adjustment.
  void ComputeLinkTypeInfo();
  LinkType StartLinkType;
  LinkType CurrentLinkType;
  std::string StaticLinkTypeFlag;
  std::string SharedLinkTypeFlag;

  // Link item parsing.
  void ComputeItemParserInfo();
  std::vector<std::string> StaticLinkExtensions;
  std::vector<std::string> SharedLinkExtensions;
  std::vector<std::string> LinkExtensions;
  std::set<std::string> LinkPrefixes;
  cmsys::RegularExpression ExtractStaticLibraryName;
  cmsys::RegularExpression ExtractSharedLibraryName;
  cmsys::RegularExpression ExtractAnyLibraryName;
  std::string SharedRegexString;
  void AddLinkPrefix(std::string const& p);
  void AddLinkExtension(std::string const& e, LinkType type);
  std::string CreateExtensionRegex(std::vector<std::string> const& exts,
                                   LinkType type);
  std::string NoCaseExpression(std::string const& str);

  // Handling of link items.
  void AddTargetItem(LinkEntry const& entry);
  void AddFullItem(LinkEntry const& entry);
  bool CheckImplicitDirItem(LinkEntry const& entry);
  void AddUserItem(LinkEntry const& entry, bool pathNotKnown);
  void AddFrameworkItem(LinkEntry const& entry);
  void AddXcFrameworkItem(LinkEntry const& entry);
  void DropDirectoryItem(BT<std::string> const& item);
  bool CheckSharedLibNoSOName(LinkEntry const& entry);
  void AddSharedLibNoSOName(LinkEntry const& entry);
  void HandleBadFullItem(LinkEntry const& entry, std::string const& file);

  // Framework info.
  void ComputeFrameworkInfo();
  void AddFrameworkPath(std::string const& p);
  std::set<std::string> FrameworkPathsEmitted;

  void AddXcFrameworkHeaderPath(std::string const& p);

  // Linker search path computation.
  std::unique_ptr<cmOrderDirectories> OrderLinkerSearchPath;
  bool FinishLinkerSearchDirectories();
  void PrintLinkPolicyDiagnosis(std::ostream&);

  void AddExternalObjectTargets();

  // Implicit link libraries and directories for linker language.
  void LoadImplicitLinkInfo();
  void AddImplicitLinkInfo();
  void AddImplicitLinkInfo(std::string const& lang);
  void AddRuntimeLinkLibrary(std::string const& lang);
  std::set<std::string> ImplicitLinkDirs;
  std::set<std::string> ImplicitLinkLibs;

  // Additional paths configured by the runtime linker
  std::vector<std::string> RuntimeLinkDirs;

  // Linker search path compatibility mode.
  std::set<std::string> OldLinkDirMask;
  std::vector<std::string> OldLinkDirItems;
  std::vector<std::string> OldUserFlagItems;
  std::set<std::string> CMP0060WarnItems;
  // Dependent library path computation.
  std::unique_ptr<cmOrderDirectories> OrderDependentRPath;
  // Runtime path computation.
  std::unique_ptr<cmOrderDirectories> OrderRuntimeSearchPath;

  bool OldLinkDirMode;
  bool IsOpenBSD;
  bool LinkDependsNoShared;
  bool RuntimeUseChrpath;
  bool NoSONameUsesPath;
  bool LinkWithRuntimePath;
  bool LinkTypeEnabled;
  bool ArchivesMayBeShared;
  bool CMP0060Warn;

  void AddLibraryRuntimeInfo(std::string const& fullPath,
                             const cmGeneratorTarget* target);
  void AddLibraryRuntimeInfo(std::string const& fullPath);

  class FeatureDescriptor
  {
  public:
    FeatureDescriptor() = default;

    const std::string Name;
    const bool Supported = false;
    const std::string Prefix;
    const std::string Suffix;
    std::string GetDecoratedItem(std::string const& library,
                                 ItemIsPath isPath) const;
    std::string GetDecoratedItem(std::string const& library,
                                 std::string const& linkItem,
                                 std::string const& defaultValue,
                                 ItemIsPath isPath) const;

  protected:
    FeatureDescriptor(std::string name, std::string itemFormat);
    FeatureDescriptor(std::string name, std::string itemPathFormat,
                      std::string itemNameFormat);
    FeatureDescriptor(std::string name, std::string prefix,
                      std::string itemPathFormat, std::string itemNameFormat,
                      std::string suffix);

    FeatureDescriptor(std::string name, std::string prefix, std::string suffix,
                      bool isGroup);

  private:
    std::string ItemPathFormat;
    std::string ItemNameFormat;
  };

  class LibraryFeatureDescriptor : public FeatureDescriptor
  {
  public:
    LibraryFeatureDescriptor(std::string name, std::string itemFormat);
    LibraryFeatureDescriptor(std::string name, std::string itemPathFormat,
                             std::string itemNameFormat);
    LibraryFeatureDescriptor(std::string name, std::string prefix,
                             std::string itemPathFormat,
                             std::string itemNameFormat, std::string suffix);
  };
  std::map<std::string, FeatureDescriptor> LibraryFeatureDescriptors;
  bool AddLibraryFeature(std::string const& feature);
  FeatureDescriptor const& GetLibraryFeature(std::string const& feature) const;
  FeatureDescriptor const* FindLibraryFeature(
    std::string const& feature) const;

  class GroupFeatureDescriptor : public FeatureDescriptor
  {
  public:
    GroupFeatureDescriptor(std::string name, std::string prefix,
                           std::string suffix);
  };
  std::map<std::string, FeatureDescriptor> GroupFeatureDescriptors;
  FeatureDescriptor const& GetGroupFeature(std::string const& feature);
};
