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

#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
#include "cmTarget.h"
#include "cmValue.h"

cmTargetPropCommandBase::cmTargetPropCommandBase(cmExecutionStatus& status)
  : Makefile(&status.GetMakefile())
  , Status(status)
{
}

void cmTargetPropCommandBase::SetError(std::string const& e)
{
  this->Status.SetError(e);
}

bool cmTargetPropCommandBase::HandleArguments(
  std::vector<std::string> const& args, std::string const& prop,
  unsigned int flags)
{
  if (args.size() < 2) {
    this->SetError("called with incorrect number of arguments");
    return false;
  }

  if (this->Makefile->IsAlias(args[0])) {
    this->SetError("can not be used on an ALIAS target.");
    return false;
  }
  // Lookup the target for which property-values are specified.
  this->Target = this->Makefile->GetGlobalGenerator()->FindTarget(args[0]);
  if (!this->Target) {
    this->Target = this->Makefile->FindTargetToUse(args[0]);
  }
  if (!this->Target) {
    this->HandleMissingTarget(args[0]);
    return false;
  }
  bool const isRegularTarget =
    (this->Target->GetType() == cmStateEnums::EXECUTABLE) ||
    (this->Target->GetType() == cmStateEnums::STATIC_LIBRARY) ||
    (this->Target->GetType() == cmStateEnums::SHARED_LIBRARY) ||
    (this->Target->GetType() == cmStateEnums::MODULE_LIBRARY) ||
    (this->Target->GetType() == cmStateEnums::OBJECT_LIBRARY) ||
    (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) ||
    (this->Target->GetType() == cmStateEnums::UNKNOWN_LIBRARY);
  bool const isCustomTarget = this->Target->GetType() == cmStateEnums::UTILITY;

  if (prop == "SOURCES") {
    if (!isRegularTarget && !isCustomTarget) {
      this->SetError("called with non-compilable target type");
      return false;
    }
  } else {
    if (!isRegularTarget) {
      this->SetError("called with non-compilable target type");
      return false;
    }
  }

  bool system = false;
  unsigned int argIndex = 1;

  if ((flags & PROCESS_SYSTEM) && args[argIndex] == "SYSTEM") {
    if (args.size() < 3) {
      this->SetError("called with incorrect number of arguments");
      return false;
    }
    system = true;
    ++argIndex;
  }

  bool prepend = false;
  if ((flags & PROCESS_BEFORE) && args[argIndex] == "BEFORE") {
    if (args.size() < 3) {
      this->SetError("called with incorrect number of arguments");
      return false;
    }
    prepend = true;
    ++argIndex;
  } else if ((flags & PROCESS_AFTER) && args[argIndex] == "AFTER") {
    if (args.size() < 3) {
      this->SetError("called with incorrect number of arguments");
      return false;
    }
    prepend = false;
    ++argIndex;
  }

  if ((flags & PROCESS_REUSE_FROM) && args[argIndex] == "REUSE_FROM") {
    if (args.size() != 3) {
      this->SetError("called with incorrect number of arguments");
      return false;
    }
    ++argIndex;

    this->Target->SetProperty("PRECOMPILE_HEADERS_REUSE_FROM", args[argIndex]);
    ++argIndex;
  }

  this->Property = prop;

  while (argIndex < args.size()) {
    if (!this->ProcessContentArgs(args, argIndex, prepend, system)) {
      return false;
    }
  }
  return true;
}

bool cmTargetPropCommandBase::ProcessContentArgs(
  std::vector<std::string> const& args, unsigned int& argIndex, bool prepend,
  bool system)
{
  std::string const& scope = args[argIndex];

  if (scope != "PUBLIC" && scope != "PRIVATE" && scope != "INTERFACE") {
    this->SetError("called with invalid arguments");
    return false;
  }

  ++argIndex;

  std::vector<std::string> content;

  for (unsigned int i = argIndex; i < args.size(); ++i, ++argIndex) {
    if (args[i] == "PUBLIC" || args[i] == "PRIVATE" ||
        args[i] == "INTERFACE") {
      break;
    }
    content.push_back(args[i]);
  }
  if (!content.empty()) {
    if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY &&
        scope != "INTERFACE" && this->Property != "SOURCES") {
      this->SetError("may only set INTERFACE properties on INTERFACE targets");
      return false;
    }
    if (this->Target->IsImported() && scope != "INTERFACE") {
      this->SetError("may only set INTERFACE properties on IMPORTED targets");
      return false;
    }
    if (this->Target->GetType() == cmStateEnums::UTILITY &&
        scope != "PRIVATE") {
      this->SetError("may only set PRIVATE properties on custom targets");
      return false;
    }
  }
  return this->PopulateTargetProperties(scope, content, prepend, system);
}

bool cmTargetPropCommandBase::PopulateTargetProperties(
  std::string const& scope, std::vector<std::string> const& content,
  bool prepend, bool system)
{
  if (content.empty()) {
    return true;
  }
  if (scope == "PRIVATE" || scope == "PUBLIC") {
    if (!this->HandleDirectContent(this->Target, content, prepend, system)) {
      return false;
    }
  }
  if (scope == "INTERFACE" || scope == "PUBLIC") {
    this->HandleInterfaceContent(this->Target, content, prepend, system);
  }
  return true;
}

void cmTargetPropCommandBase::HandleInterfaceContent(
  cmTarget* tgt, std::vector<std::string> const& content, bool prepend, bool)
{
  if (prepend) {
    std::string const propName = std::string("INTERFACE_") + this->Property;
    cmValue propValue = tgt->GetProperty(propName);
    std::string const totalContent =
      this->Join(content) + (propValue ? (";" + *propValue) : std::string());
    tgt->SetProperty(propName, totalContent);
  } else {
    tgt->AppendProperty("INTERFACE_" + this->Property, this->Join(content));
  }
}
