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

#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
#include "cmTarget.h"
#include "cmake.h"

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

  // Lookup the target for which libraries are specified.
  if (this->Makefile->IsAlias(args[0])) {
    this->SetError("can not be used on an ALIAS target.");
    return false;
  }
  this->Target =
    this->Makefile->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(
      args[0]);
  if (!this->Target) {
    this->Target = this->Makefile->FindTargetToUse(args[0]);
  }
  if (!this->Target) {
    this->HandleMissingTarget(args[0]);
    return false;
  }
  if ((this->Target->GetType() != cmStateEnums::SHARED_LIBRARY) &&
      (this->Target->GetType() != cmStateEnums::STATIC_LIBRARY) &&
      (this->Target->GetType() != cmStateEnums::OBJECT_LIBRARY) &&
      (this->Target->GetType() != cmStateEnums::MODULE_LIBRARY) &&
      (this->Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) &&
      (this->Target->GetType() != cmStateEnums::EXECUTABLE)) {
    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;
  }

  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)
{
  const std::string scope = args[argIndex];

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

  if (this->Target->IsImported()) {
    this->HandleImportedTarget(args[0]);
    return false;
  }

  if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY &&
      scope != "INTERFACE") {
    this->SetError("may only be set INTERFACE properties on INTERFACE "
                   "targets");
    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") {
      return this->PopulateTargetProperies(scope, content, prepend, system);
    }
    content.push_back(args[i]);
  }
  return this->PopulateTargetProperies(scope, content, prepend, system);
}

bool cmTargetPropCommandBase::PopulateTargetProperies(
  const std::string& scope, const std::vector<std::string>& content,
  bool prepend, bool system)
{
  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, const std::vector<std::string>& content, bool prepend, bool)
{
  if (prepend) {
    const std::string propName = std::string("INTERFACE_") + this->Property;
    const char* propValue = tgt->GetProperty(propName);
    const std::string totalContent = this->Join(content) +
      (propValue ? std::string(";") + propValue : std::string());
    tgt->SetProperty(propName, totalContent.c_str());
  } else {
    tgt->AppendProperty("INTERFACE_" + this->Property,
                        this->Join(content).c_str());
  }
}
