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

#include <sstream>
#include <string.h>

#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmake.h"

class cmExecutionStatus;

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

// cmTargetLinkLibrariesCommand
bool cmTargetLinkLibrariesCommand::InitialPass(
  std::vector<std::string> const& args, cmExecutionStatus&)
{
  // Must have at least one argument.
  if (args.empty()) {
    this->SetError("called with incorrect number of arguments");
    return false;
  }
  // Alias targets cannot be on the LHS of this command.
  if (this->Makefile->IsAlias(args[0])) {
    this->SetError("can not be used on an ALIAS target.");
    return false;
  }

  // Lookup the target for which libraries are specified.
  this->Target =
    this->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(
      args[0]);
  if (!this->Target) {
    const std::vector<cmTarget*>& importedTargets =
      this->Makefile->GetOwnedImportedTargets();
    for (cmTarget* importedTarget : importedTargets) {
      if (importedTarget->GetName() == args[0]) {
        this->Target = importedTarget;
        break;
      }
    }
  }
  if (!this->Target) {
    MessageType t = MessageType::FATAL_ERROR; // fail by default
    std::ostringstream e;
    e << "Cannot specify link libraries for target \"" << args[0] << "\" "
      << "which is not built by this project.";
    // The bad target is the only argument. Check how policy CMP0016 is set,
    // and accept, warn or fail respectively:
    if (args.size() < 2) {
      switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0016)) {
        case cmPolicies::WARN:
          t = MessageType::AUTHOR_WARNING;
          // Print the warning.
          e << "\n"
            << "CMake does not support this but it used to work accidentally "
            << "and is being allowed for compatibility."
            << "\n"
            << cmPolicies::GetPolicyWarning(cmPolicies::CMP0016);
          break;
        case cmPolicies::OLD: // OLD behavior does not warn.
          t = MessageType::MESSAGE;
          break;
        case cmPolicies::REQUIRED_IF_USED:
        case cmPolicies::REQUIRED_ALWAYS:
          e << "\n" << cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0016);
          break;
        case cmPolicies::NEW: // NEW behavior prints the error.
          break;
      }
    }
    // Now actually print the message.
    switch (t) {
      case MessageType::AUTHOR_WARNING:
        this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, e.str());
        break;
      case MessageType::FATAL_ERROR:
        this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
        cmSystemTools::SetFatalErrorOccured();
        break;
      default:
        break;
    }
    return true;
  }

  // Having a UTILITY library on the LHS is a bug.
  if (this->Target->GetType() == cmStateEnums::UTILITY) {
    std::ostringstream e;
    const char* modal = nullptr;
    MessageType messageType = MessageType::AUTHOR_WARNING;
    switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0039)) {
      case cmPolicies::WARN:
        e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0039) << "\n";
        modal = "should";
      case cmPolicies::OLD:
        break;
      case cmPolicies::REQUIRED_ALWAYS:
      case cmPolicies::REQUIRED_IF_USED:
      case cmPolicies::NEW:
        modal = "must";
        messageType = MessageType::FATAL_ERROR;
    }
    if (modal) {
      e << "Utility target \"" << this->Target->GetName() << "\" " << modal
        << " not be used as the target of a target_link_libraries call.";
      this->Makefile->IssueMessage(messageType, e.str());
      if (messageType == MessageType::FATAL_ERROR) {
        return false;
      }
    }
  }

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

  // 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.
  this->CurrentProcessingState = ProcessingLinkLibraries;

  // 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 (args[i] == "LINK_INTERFACE_LIBRARIES") {
      this->CurrentProcessingState = ProcessingPlainLinkInterface;
      if (i != 1) {
        this->Makefile->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 &&
          this->CurrentProcessingState != ProcessingKeywordPrivateInterface &&
          this->CurrentProcessingState != ProcessingKeywordPublicInterface &&
          this->CurrentProcessingState != ProcessingKeywordLinkInterface) {
        this->Makefile->IssueMessage(
          MessageType::FATAL_ERROR,
          "The INTERFACE, PUBLIC or PRIVATE option must appear as the second "
          "argument, just after the target name.");
        return true;
      }
      this->CurrentProcessingState = ProcessingKeywordLinkInterface;
    } else if (args[i] == "LINK_PUBLIC") {
      if (i != 1 &&
          this->CurrentProcessingState != ProcessingPlainPrivateInterface &&
          this->CurrentProcessingState != ProcessingPlainPublicInterface) {
        this->Makefile->IssueMessage(
          MessageType::FATAL_ERROR,
          "The LINK_PUBLIC or LINK_PRIVATE option must appear as the second "
          "argument, just after the target name.");
        return true;
      }
      this->CurrentProcessingState = ProcessingPlainPublicInterface;
    } else if (args[i] == "PUBLIC") {
      if (i != 1 &&
          this->CurrentProcessingState != ProcessingKeywordPrivateInterface &&
          this->CurrentProcessingState != ProcessingKeywordPublicInterface &&
          this->CurrentProcessingState != ProcessingKeywordLinkInterface) {
        this->Makefile->IssueMessage(
          MessageType::FATAL_ERROR,
          "The INTERFACE, PUBLIC or PRIVATE option must appear as the second "
          "argument, just after the target name.");
        return true;
      }
      this->CurrentProcessingState = ProcessingKeywordPublicInterface;
    } else if (args[i] == "LINK_PRIVATE") {
      if (i != 1 &&
          this->CurrentProcessingState != ProcessingPlainPublicInterface &&
          this->CurrentProcessingState != ProcessingPlainPrivateInterface) {
        this->Makefile->IssueMessage(
          MessageType::FATAL_ERROR,
          "The LINK_PUBLIC or LINK_PRIVATE option must appear as the second "
          "argument, just after the target name.");
        return true;
      }
      this->CurrentProcessingState = ProcessingPlainPrivateInterface;
    } else if (args[i] == "PRIVATE") {
      if (i != 1 &&
          this->CurrentProcessingState != ProcessingKeywordPrivateInterface &&
          this->CurrentProcessingState != ProcessingKeywordPublicInterface &&
          this->CurrentProcessingState != ProcessingKeywordLinkInterface) {
        this->Makefile->IssueMessage(
          MessageType::FATAL_ERROR,
          "The INTERFACE, PUBLIC or PRIVATE option must appear as the second "
          "argument, just after the target name.");
        return true;
      }
      this->CurrentProcessingState = ProcessingKeywordPrivateInterface;
    } else if (args[i] == "debug") {
      if (haveLLT) {
        this->LinkLibraryTypeSpecifierWarning(llt, DEBUG_LibraryType);
      }
      llt = DEBUG_LibraryType;
      haveLLT = true;
    } else if (args[i] == "optimized") {
      if (haveLLT) {
        this->LinkLibraryTypeSpecifierWarning(llt, OPTIMIZED_LibraryType);
      }
      llt = OPTIMIZED_LibraryType;
      haveLLT = true;
    } else if (args[i] == "general") {
      if (haveLLT) {
        this->LinkLibraryTypeSpecifierWarning(llt, GENERAL_LibraryType);
      }
      llt = GENERAL_LibraryType;
      haveLLT = true;
    } else if (haveLLT) {
      // The link type was specified by the previous argument.
      haveLLT = false;
      if (!this->HandleLibrary(args[i], llt)) {
        return false;
      }
    } else {
      // Lookup old-style cache entry if type is unspecified.  So if you
      // do a target_link_libraries(foo optimized bar) it will stay optimized
      // and not use the lookup.  As there may be the case where someone has
      // specified that a library is both debug and optimized.  (this check is
      // only there for backwards compatibility when mixing projects built
      // with old versions of CMake and new)
      llt = GENERAL_LibraryType;
      std::string linkType = args[0];
      linkType += "_LINK_TYPE";
      const char* linkTypeString = this->Makefile->GetDefinition(linkType);
      if (linkTypeString) {
        if (strcmp(linkTypeString, "debug") == 0) {
          llt = DEBUG_LibraryType;
        }
        if (strcmp(linkTypeString, "optimized") == 0) {
          llt = OPTIMIZED_LibraryType;
        }
      }
      if (!this->HandleLibrary(args[i], llt)) {
        return false;
      }
    }
  }

  // Make sure the last argument was not a library type specifier.
  if (haveLLT) {
    std::ostringstream e;
    e << "The \"" << cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[llt]
      << "\" argument must be followed by a library.";
    this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
    cmSystemTools::SetFatalErrorOccured();
  }

  const cmPolicies::PolicyStatus policy22Status =
    this->Target->GetPolicyStatusCMP0022();

  // If any of the LINK_ options were given, make sure the
  // LINK_INTERFACE_LIBRARIES target property exists.
  // Use of any of the new keywords implies awareness of
  // this property. And if no libraries are named, it should
  // result in an empty link interface.
  if ((policy22Status == cmPolicies::OLD ||
       policy22Status == cmPolicies::WARN) &&
      this->CurrentProcessingState != ProcessingLinkLibraries &&
      !this->Target->GetProperty("LINK_INTERFACE_LIBRARIES")) {
    this->Target->SetProperty("LINK_INTERFACE_LIBRARIES", "");
  }

  return true;
}

void cmTargetLinkLibrariesCommand::LinkLibraryTypeSpecifierWarning(int left,
                                                                   int right)
{
  std::ostringstream w;
  w << "Link library type specifier \""
    << cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[left]
    << "\" is followed by specifier \""
    << cmTargetLinkLibrariesCommand::LinkLibraryTypeNames[right]
    << "\" instead of a library name.  "
    << "The first specifier will be ignored.";
  this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
}

bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
                                                 cmTargetLinkLibraryType llt)
{
  if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY &&
      this->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() &&
      this->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 =
    (this->CurrentProcessingState == ProcessingPlainPrivateInterface ||
     this->CurrentProcessingState == ProcessingPlainPublicInterface ||
     this->CurrentProcessingState == ProcessingKeywordPrivateInterface ||
     this->CurrentProcessingState == ProcessingKeywordPublicInterface ||
     this->CurrentProcessingState == ProcessingKeywordLinkInterface)
    ? cmTarget::KeywordTLLSignature
    : cmTarget::PlainTLLSignature;
  if (!this->Target->PushTLLCommandTrace(
        sig, this->Makefile->GetExecutionContext())) {
    std::ostringstream e;
    const char* modal = nullptr;
    MessageType messageType = MessageType::AUTHOR_WARNING;
    switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0023)) {
      case cmPolicies::WARN:
        e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0023) << "\n";
        modal = "should";
      case cmPolicies::OLD:
        break;
      case cmPolicies::REQUIRED_ALWAYS:
      case cmPolicies::REQUIRED_IF_USED:
      case cmPolicies::NEW:
        modal = "must";
        messageType = MessageType::FATAL_ERROR;
    }

    if (modal) {
      // If the sig is a keyword form and there is a conflict, the existing
      // form must be the plain form.
      const char* 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 " << modal
        << " be either all-keyword or all-plain.\n";
      this->Target->GetTllSignatureTraces(e,
                                          sig == cmTarget::KeywordTLLSignature
                                            ? cmTarget::PlainTLLSignature
                                            : cmTarget::KeywordTLLSignature);
      this->Makefile->IssueMessage(messageType, e.str());
      if (messageType == MessageType::FATAL_ERROR) {
        return false;
      }
    }
  }

  bool warnRemoteInterface = false;
  bool rejectRemoteLinking = false;
  bool encodeRemoteReference = false;
  if (this->Makefile != this->Target->GetMakefile()) {
    // The LHS target was created in another directory.
    switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0079)) {
      case cmPolicies::WARN:
        warnRemoteInterface = true;
        CM_FALLTHROUGH;
      case cmPolicies::OLD:
        rejectRemoteLinking = true;
        break;
      case cmPolicies::REQUIRED_ALWAYS:
      case cmPolicies::REQUIRED_IF_USED:
      case cmPolicies::NEW:
        encodeRemoteReference = true;
        break;
    }
  }

  std::string libRef;
  if (encodeRemoteReference && !cmSystemTools::FileIsFullPath(lib)) {
    // This is a library name added by a caller that is not in the
    // same directory as the target was created.  Add a suffix to
    // the name to tell ResolveLinkItem to look up the name in the
    // caller's directory.
    cmDirectoryId const dirId = this->Makefile->GetDirectoryId();
    libRef = lib + CMAKE_DIRECTORY_ID_SEP + dirId.String;
  } else {
    // This is an absolute path or a library name added by a caller
    // in the same directory as the target was created.  We can use
    // the original name directly.
    libRef = lib;
  }

  // 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 (this->CurrentProcessingState != ProcessingKeywordLinkInterface &&
      this->CurrentProcessingState != ProcessingPlainLinkInterface) {

    if (rejectRemoteLinking) {
      std::ostringstream e;
      e << "Attempt to add link library \"" << lib << "\" to target \""
        << this->Target->GetName()
        << "\" which is not built in this directory.\n"
        << "This is allowed only when policy CMP0079 is set to NEW.";
      this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
      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()) {
      std::ostringstream e;
      e << "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->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
    }

    this->Target->AddLinkLibrary(*this->Makefile, lib, libRef, llt);
  }

  if (warnRemoteInterface) {
    std::ostringstream w;
    /* clang-format off */
    w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0079) << "\n"
      "Target\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.";
    /* clang-format on */
    this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
  }

  // 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 (this->CurrentProcessingState == ProcessingKeywordPrivateInterface ||
      this->CurrentProcessingState == ProcessingPlainPrivateInterface) {
    if (this->Target->GetType() == cmStateEnums::STATIC_LIBRARY ||
        this->Target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
      std::string configLib =
        this->Target->GetDebugGeneratorExpressions(libRef, llt);
      if (cmGeneratorExpression::IsValidTargetName(lib) ||
          cmGeneratorExpression::Find(lib) != std::string::npos) {
        configLib = "$<LINK_ONLY:" + configLib + ">";
      }
      this->Target->AppendProperty("INTERFACE_LINK_LIBRARIES",
                                   configLib.c_str());
    }
    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->Target->AppendProperty(
    "INTERFACE_LINK_LIBRARIES",
    this->Target->GetDebugGeneratorExpressions(libRef, llt).c_str());

  // Stop processing if called without any keyword.
  if (this->CurrentProcessingState == ProcessingLinkLibraries) {
    return true;
  }
  // Stop processing if policy CMP0022 is set to NEW.
  const cmPolicies::PolicyStatus policy22Status =
    this->Target->GetPolicyStatusCMP0022();
  if (policy22Status != cmPolicies::OLD &&
      policy22Status != cmPolicies::WARN) {
    return true;
  }
  // Stop processing if called with an INTERFACE library on the LHS.
  if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
    return true;
  }

  // Handle (additional) backward-compatibility case where the command was
  // called with PUBLIC / INTERFACE / LINK_PUBLIC / LINK_INTERFACE_LIBRARIES.
  // (The policy CMP0022 is not set to NEW.)
  {
    // Get the list of configurations considered to be DEBUG.
    std::vector<std::string> debugConfigs =
      this->Makefile->GetCMakeInstance()->GetDebugConfigs();
    std::string prop;

    // Include this library in the link interface for the target.
    if (llt == DEBUG_LibraryType || llt == GENERAL_LibraryType) {
      // Put in the DEBUG configuration interfaces.
      for (std::string const& dc : debugConfigs) {
        prop = "LINK_INTERFACE_LIBRARIES_";
        prop += dc;
        this->Target->AppendProperty(prop, libRef.c_str());
      }
    }
    if (llt == OPTIMIZED_LibraryType || llt == GENERAL_LibraryType) {
      // Put in the non-DEBUG configuration interfaces.
      this->Target->AppendProperty("LINK_INTERFACE_LIBRARIES", libRef.c_str());

      // Make sure the DEBUG configuration interfaces exist so that the
      // general one will not be used as a fall-back.
      for (std::string const& dc : debugConfigs) {
        prop = "LINK_INTERFACE_LIBRARIES_";
        prop += dc;
        if (!this->Target->GetProperty(prop)) {
          this->Target->SetProperty(prop, "");
        }
      }
    }
  }
  return true;
}
