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

#include <cstring>
#include <sstream>

#include "cmAlgorithms.h"
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
#include "cmPolicies.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmake.h"

class cmExecutionStatus;

bool cmTargetSourcesCommand::InitialPass(std::vector<std::string> const& args,
                                         cmExecutionStatus&)
{
  return this->HandleArguments(args, "SOURCES");
}

void cmTargetSourcesCommand::HandleInterfaceContent(
  cmTarget* tgt, const std::vector<std::string>& content, bool prepend,
  bool system)
{
  cmTargetPropCommandBase::HandleInterfaceContent(
    tgt, ConvertToAbsoluteContent(tgt, content, true), prepend, system);
}

void cmTargetSourcesCommand::HandleMissingTarget(const std::string& name)
{
  std::ostringstream e;
  e << "Cannot specify sources for target \"" << name
    << "\" "
       "which is not built by this project.";
  this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}

std::string cmTargetSourcesCommand::Join(
  const std::vector<std::string>& content)
{
  return cmJoin(content, ";");
}

bool cmTargetSourcesCommand::HandleDirectContent(
  cmTarget* tgt, const std::vector<std::string>& content, bool, bool)
{
  tgt->AppendProperty(
    "SOURCES",
    this->Join(ConvertToAbsoluteContent(tgt, content, false)).c_str());
  return true; // Successfully handled.
}

std::vector<std::string> cmTargetSourcesCommand::ConvertToAbsoluteContent(
  cmTarget* tgt, const std::vector<std::string>& content,
  bool isInterfaceContent)
{
  // Skip conversion in case old behavior has been explictly requested
  if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0076) ==
      cmPolicies::OLD) {
    return content;
  }

  bool changedPath = false;
  std::vector<std::string> absoluteContent;
  absoluteContent.reserve(content.size());
  for (std::string const& src : content) {
    std::string absoluteSrc;
    if (cmSystemTools::FileIsFullPath(src) ||
        cmGeneratorExpression::Find(src) == 0 ||
        (!isInterfaceContent &&
         strcmp(this->Makefile->GetCurrentSourceDirectory(),
                tgt->GetMakefile()->GetCurrentSourceDirectory()) == 0)) {
      absoluteSrc = src;
    } else {
      changedPath = true;
      absoluteSrc = this->Makefile->GetCurrentSourceDirectory();
      absoluteSrc += "/";
      absoluteSrc += src;
    }
    absoluteContent.push_back(absoluteSrc);
  }

  if (!changedPath) {
    return content;
  }

  bool issueMessage = true;
  bool useAbsoluteContent = false;
  std::ostringstream e;
  switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0076)) {
    case cmPolicies::WARN:
      e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0076) << "\n";
      break;
    case cmPolicies::OLD:
      issueMessage = false;
      break;
    case cmPolicies::REQUIRED_ALWAYS:
    case cmPolicies::REQUIRED_IF_USED:
      this->Makefile->IssueMessage(
        cmake::FATAL_ERROR,
        cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0076));
      break;
    case cmPolicies::NEW: {
      issueMessage = false;
      useAbsoluteContent = true;
      break;
    }
  }

  if (issueMessage) {
    if (isInterfaceContent) {
      e << "An interface source of target \"" << tgt->GetName()
        << "\" has a relative path.";
    } else {
      e << "A private source from a directory other than that of target \""
        << tgt->GetName() << "\" has a relative path.";
    }
    this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, e.str());
  }

  return useAbsoluteContent ? absoluteContent : content;
}
