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

#include "cmTargetPropertyComputer.h"

#include <cctype>
#include <sstream>
#include <unordered_set>

#include "cmMessageType.h"
#include "cmMessenger.h"
#include "cmPolicies.h"
#include "cmStateSnapshot.h"

bool cmTargetPropertyComputer::HandleLocationPropertyPolicy(
  std::string const& tgtName, cmMessenger* messenger,
  cmListFileBacktrace const& context)
{
  std::ostringstream e;
  const char* modal = nullptr;
  MessageType messageType = MessageType::AUTHOR_WARNING;
  switch (context.GetBottom().GetPolicy(cmPolicies::CMP0026)) {
    case cmPolicies::WARN:
      e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0026) << "\n";
      modal = "should";
    case cmPolicies::OLD:
      break;
    case cmPolicies::REQUIRED_ALWAYS:
    case cmPolicies::REQUIRED_IF_USED:
    case cmPolicies::NEW:
      modal = "may";
      messageType = MessageType::FATAL_ERROR;
  }

  if (modal) {
    e << "The LOCATION property " << modal << " not be read from target \""
      << tgtName
      << "\".  Use the target name directly with "
         "add_custom_command, or use the generator expression $<TARGET_FILE>, "
         "as appropriate.\n";
    messenger->IssueMessage(messageType, e.str(), context);
  }

  return messageType != MessageType::FATAL_ERROR;
}

bool cmTargetPropertyComputer::WhiteListedInterfaceProperty(
  const std::string& prop)
{
  if (cmHasLiteralPrefix(prop, "INTERFACE_")) {
    return true;
  }
  if (cmHasLiteralPrefix(prop, "_")) {
    return true;
  }
  if (std::islower(prop[0])) {
    return true;
  }
  static std::unordered_set<std::string> builtIns;
  if (builtIns.empty()) {
    builtIns.insert("COMPATIBLE_INTERFACE_BOOL");
    builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MAX");
    builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MIN");
    builtIns.insert("COMPATIBLE_INTERFACE_STRING");
    builtIns.insert("EXPORT_NAME");
    builtIns.insert("IMPORTED");
    builtIns.insert("IMPORTED_GLOBAL");
    builtIns.insert("MANUALLY_ADDED_DEPENDENCIES");
    builtIns.insert("NAME");
    builtIns.insert("TYPE");
  }

  if (builtIns.count(prop)) {
    return true;
  }

  if (prop == "IMPORTED_CONFIGURATIONS" || prop == "IMPORTED_LIBNAME" ||
      cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME_") ||
      cmHasLiteralPrefix(prop, "MAP_IMPORTED_CONFIG_")) {
    return true;
  }

  // This property should not be allowed but was incorrectly added in
  // CMake 3.8.  We can't remove it from the whitelist without breaking
  // projects that try to set it.  One day we could warn about this, but
  // for now silently accept it.
  if (prop == "NO_SYSTEM_FROM_IMPORTED") {
    return true;
  }

  return false;
}

bool cmTargetPropertyComputer::PassesWhitelist(
  cmStateEnums::TargetType tgtType, std::string const& prop,
  cmMessenger* messenger, cmListFileBacktrace const& context)
{
  if (tgtType == cmStateEnums::INTERFACE_LIBRARY &&
      !WhiteListedInterfaceProperty(prop)) {
    std::ostringstream e;
    e << "INTERFACE_LIBRARY targets may only have whitelisted properties.  "
         "The property \""
      << prop << "\" is not allowed.";
    messenger->IssueMessage(MessageType::FATAL_ERROR, e.str(), context);
    return false;
  }
  return true;
}
