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

#include <utility>

#include "cmGeneratorExpression.h"
#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetPropCommandBase.h"

namespace {

std::vector<std::string> ConvertToAbsoluteContent(
  const std::vector<std::string>& content, std::string const& baseDir)
{
  std::vector<std::string> absoluteContent;
  absoluteContent.reserve(content.size());
  for (std::string const& src : content) {
    std::string absoluteSrc;
    // Use '<foo.h>' and '"foo.h"' includes and absolute paths as-is.
    // Interpret relative paths with respect to the source directory.
    // If the path starts in a generator expression, assume it is absolute.
    if (cmHasLiteralPrefix(src, "<") || cmHasLiteralPrefix(src, "\"") ||
        cmSystemTools::FileIsFullPath(src) ||
        cmGeneratorExpression::Find(src) == 0) {
      absoluteSrc = src;
    } else {
      absoluteSrc = cmStrCat(baseDir, '/', src);
    }
    absoluteContent.emplace_back(std::move(absoluteSrc));
  }
  return absoluteContent;
}

class TargetPrecompileHeadersImpl : public cmTargetPropCommandBase
{
public:
  using cmTargetPropCommandBase::cmTargetPropCommandBase;

private:
  bool HandleDirectContent(cmTarget* tgt,
                           const std::vector<std::string>& content,
                           bool /*prepend*/, bool /*system*/) override
  {
    std::string const& base = this->Makefile->GetCurrentSourceDirectory();
    tgt->AppendProperty("PRECOMPILE_HEADERS",
                        this->Join(ConvertToAbsoluteContent(content, base)),
                        this->Makefile->GetBacktrace());
    return true;
  }

  void HandleInterfaceContent(cmTarget* tgt,
                              const std::vector<std::string>& content,
                              bool prepend, bool system) override
  {
    std::string const& base = this->Makefile->GetCurrentSourceDirectory();
    this->cmTargetPropCommandBase::HandleInterfaceContent(
      tgt, ConvertToAbsoluteContent(content, base), prepend, system);
  }

  void HandleMissingTarget(const std::string& name) override
  {
    this->Makefile->IssueMessage(
      MessageType::FATAL_ERROR,
      cmStrCat("Cannot specify precompile headers for target \"", name,
               "\" which is not built by this project."));
  }

  std::string Join(const std::vector<std::string>& content) override
  {
    return cmList::to_string(content);
  }
};

} // namespace

bool cmTargetPrecompileHeadersCommand(std::vector<std::string> const& args,
                                      cmExecutionStatus& status)
{
  return TargetPrecompileHeadersImpl(status).HandleArguments(
    args, "PRECOMPILE_HEADERS",
    TargetPrecompileHeadersImpl::PROCESS_REUSE_FROM);
}
