/* 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 <sstream>

#include "cmAlgorithms.h"
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmSystemTools.h"
#include "cmTarget.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(MessageType::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 explicitly 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 &&
         (this->Makefile->GetCurrentSourceDirectory() ==
          tgt->GetMakefile()->GetCurrentSourceDirectory()))) {
      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(
        MessageType::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(MessageType::AUTHOR_WARNING, e.str());
  }

  return useAbsoluteContent ? absoluteContent : content;
}
