/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst or https://cmake.org/licensing for details.  */
#include "cmTargetLinkLibrariesCommand.h"

#include <cassert>
#include <cstddef>
#include <memory>
#include <sstream>
#include <unordered_set>
#include <utility>

#include <cm/optional>
#include <cm/string_view>

#include "cmDiagnostics.h"
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetLinkLibraryType.h"

namespace {

enum ProcessingState
{
  ProcessingLinkLibraries,
  ProcessingPlainLinkInterface,
  ProcessingKeywordLinkInterface,
  ProcessingPlainPublicInterface,
  ProcessingKeywordPublicInterface,
  ProcessingPlainPrivateInterface,
  ProcessingKeywordPrivateInterface
};

char const* LinkLibraryTypeNames[3] = { "general", "debug", "optimized" };

struct TLL
{
  cmMakefile& Makefile;
  cmTarget* Target;
  bool WarnRemoteInterface = false;
  bool RejectRemoteLinking = false;
  bool EncodeRemoteReference = false;
  std::string DirectoryId;
  std::unordered_set<std::string> Props;

  TLL(cmMakefile& mf, cmTarget* target);
  ~TLL();

  bool HandleLibrary(ProcessingState currentProcessingState,
                     std::string const& lib, cmTargetLinkLibraryType llt);
  void AppendProperty(std::string const& prop, std::string const& value);
  void AffectsProperty(std::string const& prop);
};

} // namespace

static void LinkLibraryTypeSpecifierWarning(cmMakefile& mf, int left,
                                            int right);

bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args,
                                  cmExecutionStatus& status)
{
  // Must have at least one argument.
  if (args.empty()) {
    status.SetError("called with incorrect number of arguments");
    return false;
  }

  cmMakefile& mf = status.GetMakefile();

  // Alias targets cannot be on the LHS of this command.
  if (mf.IsAlias(args[0])) {
    status.SetError("can not be used on an ALIAS target.");
    return false;
  }

  // Lookup the target for which libraries are specified.
  cmTarget* target = mf.GetGlobalGenerator()->FindTarget(args[0]);
  if (!target) {
    for (auto const& importedTarget : mf.GetOwnedImportedTargets()) {
      if (importedTarget->GetName() == args[0] &&
          !importedTarget->IsForeign()) {
        target = importedTarget.get();
        break;
      }
    }
  }
  if (!target) {
    mf.IssueMessage(MessageType::FATAL_ERROR,
                    cmStrCat("Cannot specify link libraries for target \"",
                             args[0],
                             "\" which is not built by this project."));
    cmSystemTools::SetFatalErrorOccurred();
    return true;
  }

  if (target->IsSymbolic()) {
    status.SetError("can not be used on a SYMBOLIC target.");
    return false;
  }

  // Having a UTILITY library on the LHS is a bug.
  if (target->GetType() == cmStateEnums::UTILITY) {
    mf.IssueMessage(
      MessageType::FATAL_ERROR,
      cmStrCat(
        "Utility target \"", target->GetName(),
        "\" must not be used as the target of a target_link_libraries call."));
    return false;
  }

  // But we might not have any libs after variable expansion.
  if (args.size() < 2) {
    return true;
  }

  TLL tll(mf, target);

  // Keep track of link configuration specifiers.
  cmTargetLinkLibraryType llt = GENERAL_LibraryType;
  bool haveLLT = false;

  // Start with primary linking and switch to link interface
  // specification if the keyword is encountered as the first argument.
  ProcessingState currentProcessingState = ProcessingLinkLibraries;

  // Accumulate consecutive non-keyword arguments into one entry in
  // order to handle unquoted generator expressions containing ';'.
  std::size_t genexNesting = 0;
  cm::optional<std::string> currentEntry;
  auto processCurrentEntry = [&]() -> bool {
    // FIXME: Warn about partial genex if genexNesting > 0?
    genexNesting = 0;
    if (currentEntry) {
      assert(!haveLLT);
      if (!tll.HandleLibrary(currentProcessingState, *currentEntry,
                             GENERAL_LibraryType)) {
        return false;
      }
      currentEntry = cm::nullopt;
    }
    return true;
  };
  auto extendCurrentEntry = [&currentEntry](std::string const& arg) {
    if (currentEntry) {
      currentEntry = cmStrCat(*currentEntry, ';', arg);
    } else {
      currentEntry = arg;
    }
  };

  // Keep this list in sync with the keyword dispatch below.
  static std::unordered_set<std::string> const keywords{
    "LINK_INTERFACE_LIBRARIES",
    "INTERFACE",
    "LINK_PUBLIC",
    "PUBLIC",
    "LINK_PRIVATE",
    "PRIVATE",
    "debug",
    "optimized",
    "general",
  };

  // Add libraries, note that there is an optional prefix
  // of debug and optimized that can be used.
  for (unsigned int i = 1; i < args.size(); ++i) {
    if (keywords.count(args[i])) {
      // A keyword argument terminates any accumulated partial genex.
      if (!processCurrentEntry()) {
        return false;
      }

      // Process this keyword argument.
      if (args[i] == "LINK_INTERFACE_LIBRARIES") {
        currentProcessingState = ProcessingPlainLinkInterface;
        if (i != 1) {
          mf.IssueMessage(
            MessageType::FATAL_ERROR,
            "The LINK_INTERFACE_LIBRARIES option must appear as the "
            "second argument, just after the target name.");
          return true;
        }
      } else if (args[i] == "INTERFACE") {
        if (i != 1 &&
            currentProcessingState != ProcessingKeywordPrivateInterface &&
            currentProcessingState != ProcessingKeywordPublicInterface &&
            currentProcessingState != ProcessingKeywordLinkInterface) {
          mf.IssueMessage(MessageType::FATAL_ERROR,
                          "The INTERFACE, PUBLIC or PRIVATE option must "
                          "appear as the second argument, just after the "
                          "target name.");
          return true;
        }
        currentProcessingState = ProcessingKeywordLinkInterface;
      } else if (args[i] == "LINK_PUBLIC") {
        if (i != 1 &&
            currentProcessingState != ProcessingPlainPrivateInterface &&
            currentProcessingState != ProcessingPlainPublicInterface) {
          mf.IssueMessage(
            MessageType::FATAL_ERROR,
            "The LINK_PUBLIC or LINK_PRIVATE option must appear as the "
            "second argument, just after the target name.");
          return true;
        }
        currentProcessingState = ProcessingPlainPublicInterface;
      } else if (args[i] == "PUBLIC") {
        if (i != 1 &&
            currentProcessingState != ProcessingKeywordPrivateInterface &&
            currentProcessingState != ProcessingKeywordPublicInterface &&
            currentProcessingState != ProcessingKeywordLinkInterface) {
          mf.IssueMessage(MessageType::FATAL_ERROR,
                          "The INTERFACE, PUBLIC or PRIVATE option must "
                          "appear as the second argument, just after the "
                          "target name.");
          return true;
        }
        currentProcessingState = ProcessingKeywordPublicInterface;
      } else if (args[i] == "LINK_PRIVATE") {
        if (i != 1 &&
            currentProcessingState != ProcessingPlainPublicInterface &&
            currentProcessingState != ProcessingPlainPrivateInterface) {
          mf.IssueMessage(
            MessageType::FATAL_ERROR,
            "The LINK_PUBLIC or LINK_PRIVATE option must appear as the "
            "second argument, just after the target name.");
          return true;
        }
        currentProcessingState = ProcessingPlainPrivateInterface;
      } else if (args[i] == "PRIVATE") {
        if (i != 1 &&
            currentProcessingState != ProcessingKeywordPrivateInterface &&
            currentProcessingState != ProcessingKeywordPublicInterface &&
            currentProcessingState != ProcessingKeywordLinkInterface) {
          mf.IssueMessage(MessageType::FATAL_ERROR,
                          "The INTERFACE, PUBLIC or PRIVATE option must "
                          "appear as the second argument, just after the "
                          "target name.");
          return true;
        }
        currentProcessingState = ProcessingKeywordPrivateInterface;
      } else if (args[i] == "debug") {
        if (haveLLT) {
          LinkLibraryTypeSpecifierWarning(mf, llt, DEBUG_LibraryType);
        }
        llt = DEBUG_LibraryType;
        haveLLT = true;
      } else if (args[i] == "optimized") {
        if (haveLLT) {
          LinkLibraryTypeSpecifierWarning(mf, llt, OPTIMIZED_LibraryType);
        }
        llt = OPTIMIZED_LibraryType;
        haveLLT = true;
      } else if (args[i] == "general") {
        if (haveLLT) {
          LinkLibraryTypeSpecifierWarning(mf, llt, GENERAL_LibraryType);
        }
        llt = GENERAL_LibraryType;
        haveLLT = true;
      }
    } else if (haveLLT) {
      // The link type was specified by the previous argument.
      haveLLT = false;
      assert(!currentEntry);
      if (!tll.HandleLibrary(currentProcessingState, args[i], llt)) {
        return false;
      }
      llt = GENERAL_LibraryType;
    } else {
      // Track the genex nesting level.
      {
        cm::string_view arg = args[i];
        for (std::string::size_type pos = 0; pos < arg.size(); ++pos) {
          cm::string_view cur = arg.substr(pos);
          if (cmHasLiteralPrefix(cur, "$<")) {
            ++genexNesting;
            ++pos;
          } else if (genexNesting > 0 && cmHasPrefix(cur, '>')) {
            --genexNesting;
          }
        }
      }

      // Accumulate this argument in the current entry.
      extendCurrentEntry(args[i]);

      // Process this entry if it does not end inside a genex.
      if (genexNesting == 0) {
        if (!processCurrentEntry()) {
          return false;
        }
      }
    }
  }

  // Process the last accumulated partial genex, if any.
  if (!processCurrentEntry()) {
    return false;
  }

  // Make sure the last argument was not a library type specifier.
  if (haveLLT) {
    mf.IssueMessage(MessageType::FATAL_ERROR,
                    cmStrCat("The \"", LinkLibraryTypeNames[llt],
                             "\" argument must be followed by a library."));
    cmSystemTools::SetFatalErrorOccurred();
  }

  return true;
}

static void LinkLibraryTypeSpecifierWarning(cmMakefile& mf, int left,
                                            int right)
{
  mf.IssueDiagnostic(
    cmDiagnostics::CMD_AUTHOR,
    cmStrCat(
      "Link library type specifier \"", LinkLibraryTypeNames[left],
      "\" is followed by specifier \"", LinkLibraryTypeNames[right],
      "\" instead of a library name.  The first specifier will be ignored."));
}

namespace {

TLL::TLL(cmMakefile& mf, cmTarget* target)
  : Makefile(mf)
  , Target(target)
{
  if (&this->Makefile != this->Target->GetMakefile()) {
    // The LHS target was created in another directory.
    switch (this->Makefile.GetPolicyStatus(cmPolicies::CMP0079)) {
      case cmPolicies::WARN:
        this->WarnRemoteInterface = true;
        CM_FALLTHROUGH;
      case cmPolicies::OLD:
        this->RejectRemoteLinking = true;
        break;
      case cmPolicies::NEW:
        this->EncodeRemoteReference = true;
        break;
    }
  }
  if (this->EncodeRemoteReference) {
    cmDirectoryId const dirId = this->Makefile.GetDirectoryId();
    this->DirectoryId = cmStrCat(CMAKE_DIRECTORY_ID_SEP, dirId.String);
  }
}

bool TLL::HandleLibrary(ProcessingState currentProcessingState,
                        std::string const& lib, cmTargetLinkLibraryType llt)
{
  if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY &&
      currentProcessingState != ProcessingKeywordLinkInterface) {
    this->Makefile.IssueMessage(
      MessageType::FATAL_ERROR,
      "INTERFACE library can only be used with the INTERFACE keyword of "
      "target_link_libraries");
    return false;
  }
  if (this->Target->IsImported() &&
      currentProcessingState != ProcessingKeywordLinkInterface) {
    this->Makefile.IssueMessage(
      MessageType::FATAL_ERROR,
      "IMPORTED library can only be used with the INTERFACE keyword of "
      "target_link_libraries");
    return false;
  }

  cmTarget::TLLSignature sig =
    (currentProcessingState == ProcessingPlainPrivateInterface ||
     currentProcessingState == ProcessingPlainPublicInterface ||
     currentProcessingState == ProcessingKeywordPrivateInterface ||
     currentProcessingState == ProcessingKeywordPublicInterface ||
     currentProcessingState == ProcessingKeywordLinkInterface)
    ? cmTarget::KeywordTLLSignature
    : cmTarget::PlainTLLSignature;
  if (!this->Target->PushTLLCommandTrace(
        sig, this->Makefile.GetBacktrace().Top())) {
    std::ostringstream e;
    // If the sig is a keyword form and there is a conflict, the existing
    // form must be the plain form.
    char const* existingSig =
      (sig == cmTarget::KeywordTLLSignature ? "plain" : "keyword");
    e << "The " << existingSig
      << " signature for target_link_libraries has "
         "already been used with the target \""
      << this->Target->GetName()
      << "\".  All uses of target_link_libraries with a target must "
      << " be either all-keyword or all-plain.\n";
    this->Target->GetTllSignatureTraces(e,
                                        sig == cmTarget::KeywordTLLSignature
                                          ? cmTarget::PlainTLLSignature
                                          : cmTarget::KeywordTLLSignature);
    this->Makefile.IssueMessage(MessageType::FATAL_ERROR, e.str());
    return false;
  }

  // Handle normal case where the command was called with another keyword than
  // INTERFACE / LINK_INTERFACE_LIBRARIES or none at all. (The "LINK_LIBRARIES"
  // property of the target on the LHS shall be populated.)
  if (currentProcessingState != ProcessingKeywordLinkInterface &&
      currentProcessingState != ProcessingPlainLinkInterface) {

    if (this->RejectRemoteLinking) {
      this->Makefile.IssueMessage(
        MessageType::FATAL_ERROR,
        cmStrCat("Attempt to add link library \"", lib, "\" to target \"",
                 this->Target->GetName(),
                 "\" which is not built in this "
                 "directory.\nThis is allowed only when policy CMP0079 "
                 "is set to NEW."));
      return false;
    }

    cmTarget* tgt = this->Makefile.GetGlobalGenerator()->FindTarget(lib);

    if (tgt && (tgt->GetType() != cmStateEnums::STATIC_LIBRARY) &&
        (tgt->GetType() != cmStateEnums::SHARED_LIBRARY) &&
        (tgt->GetType() != cmStateEnums::UNKNOWN_LIBRARY) &&
        (tgt->GetType() != cmStateEnums::OBJECT_LIBRARY) &&
        (tgt->GetType() != cmStateEnums::INTERFACE_LIBRARY) &&
        !tgt->IsExecutableWithExports()) {
      this->Makefile.IssueMessage(
        MessageType::FATAL_ERROR,
        cmStrCat(
          "Target \"", lib, "\" of type ",
          cmState::GetTargetTypeName(tgt->GetType()),
          " may not be linked into another target. One may link only to "
          "INTERFACE, OBJECT, STATIC or SHARED libraries, or to "
          "executables with the ENABLE_EXPORTS property set."));
    }

    this->AffectsProperty("LINK_LIBRARIES");
    this->Target->AddLinkLibrary(this->Makefile, lib, llt);
  }

  if (this->WarnRemoteInterface) {
    this->Makefile.IssueDiagnostic(
      cmDiagnostics::CMD_POLICY,
      cmStrCat(
        cmPolicies::GetPolicyWarning(cmPolicies::CMP0079), "\nTarget\n  ",
        this->Target->GetName(),
        "\nis not created in this "
        "directory.  For compatibility with older versions of CMake, link "
        "library\n  ",
        lib,
        "\nwill be looked up in the directory in which "
        "the target was created rather than in this calling directory."));
  }

  // Handle (additional) case where the command was called with PRIVATE /
  // LINK_PRIVATE and stop its processing. (The "INTERFACE_LINK_LIBRARIES"
  // property of the target on the LHS shall only be populated if it is a
  // STATIC library.)
  if (currentProcessingState == ProcessingKeywordPrivateInterface ||
      currentProcessingState == ProcessingPlainPrivateInterface) {
    if (this->Target->GetType() == cmStateEnums::STATIC_LIBRARY ||
        this->Target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
      // TODO: Detect and no-op `$<COMPILE_ONLY>` genexes here.
      std::string configLib =
        this->Target->GetDebugGeneratorExpressions(lib, llt);
      if (cmGeneratorExpression::IsValidTargetName(lib) ||
          cmGeneratorExpression::Find(lib) != std::string::npos) {
        configLib = "$<LINK_ONLY:" + configLib + ">";
      }
      this->AppendProperty("INTERFACE_LINK_LIBRARIES", configLib);
    }
    return true;
  }

  // Handle general case where the command was called with another keyword than
  // PRIVATE / LINK_PRIVATE or none at all. (The "INTERFACE_LINK_LIBRARIES"
  // property of the target on the LHS shall be populated.)
  this->AppendProperty("INTERFACE_LINK_LIBRARIES",
                       this->Target->GetDebugGeneratorExpressions(lib, llt));
  return true;
}

void TLL::AppendProperty(std::string const& prop, std::string const& value)
{
  this->AffectsProperty(prop);
  this->Target->AppendProperty(prop, value, this->Makefile.GetBacktrace());
}

void TLL::AffectsProperty(std::string const& prop)
{
  if (!this->EncodeRemoteReference) {
    return;
  }
  // Add a wrapper to the expression to tell LookupLinkItem to look up
  // names in the caller's directory.
  if (this->Props.insert(prop).second) {
    this->Target->AppendProperty(prop, this->DirectoryId,
                                 this->Makefile.GetBacktrace());
  }
}

TLL::~TLL()
{
  for (std::string const& prop : this->Props) {
    this->Target->AppendProperty(prop, CMAKE_DIRECTORY_ID_SEP,
                                 this->Makefile.GetBacktrace());
  }
}

} // namespace
