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

#include "cmAlgorithms.h"
#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionEvaluator.h"
#include "cmGeneratorTarget.h"
#include "cmLocalGenerator.h"
#include "cmMessageType.h"
#include "cmake.h"

#include <sstream>
#include <string.h>
#include <utility>

cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
  cmListFileBacktrace backtrace, cmGeneratorTarget const* target,
  std::string property, const GeneratorExpressionContent* content,
  cmGeneratorExpressionDAGChecker* parent)
  : Parent(parent)
  , Target(target)
  , Property(std::move(property))
  , Content(content)
  , Backtrace(std::move(backtrace))
  , TransitivePropertiesOnly(false)
{
  Initialize();
}

cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
  cmGeneratorTarget const* target, std::string property,
  const GeneratorExpressionContent* content,
  cmGeneratorExpressionDAGChecker* parent)
  : Parent(parent)
  , Target(target)
  , Property(std::move(property))
  , Content(content)
  , Backtrace()
  , TransitivePropertiesOnly(false)
{
  Initialize();
}

void cmGeneratorExpressionDAGChecker::Initialize()
{
  const cmGeneratorExpressionDAGChecker* top = this;
  const cmGeneratorExpressionDAGChecker* p = this->Parent;
  while (p) {
    top = p;
    p = p->Parent;
  }
  this->CheckResult = this->CheckGraph();

#define TEST_TRANSITIVE_PROPERTY_METHOD(METHOD) top->METHOD() ||

  if (CheckResult == DAG &&
      (CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(
        TEST_TRANSITIVE_PROPERTY_METHOD) false)) // NOLINT(*)
#undef TEST_TRANSITIVE_PROPERTY_METHOD
  {
    std::map<cmGeneratorTarget const*, std::set<std::string>>::const_iterator
      it = top->Seen.find(this->Target);
    if (it != top->Seen.end()) {
      const std::set<std::string>& propSet = it->second;
      if (propSet.find(this->Property) != propSet.end()) {
        this->CheckResult = ALREADY_SEEN;
        return;
      }
    }
    const_cast<cmGeneratorExpressionDAGChecker*>(top)
      ->Seen[this->Target]
      .insert(this->Property);
  }
}

cmGeneratorExpressionDAGChecker::Result
cmGeneratorExpressionDAGChecker::Check() const
{
  return this->CheckResult;
}

void cmGeneratorExpressionDAGChecker::ReportError(
  cmGeneratorExpressionContext* context, const std::string& expr)
{
  if (this->CheckResult == DAG) {
    return;
  }

  context->HadError = true;
  if (context->Quiet) {
    return;
  }

  const cmGeneratorExpressionDAGChecker* parent = this->Parent;

  if (parent && !parent->Parent) {
    std::ostringstream e;
    e << "Error evaluating generator expression:\n"
      << "  " << expr << "\n"
      << "Self reference on target \"" << context->HeadTarget->GetName()
      << "\".\n";
    context->LG->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
                                                  e.str(), parent->Backtrace);
    return;
  }

  {
    std::ostringstream e;
    /* clang-format off */
  e << "Error evaluating generator expression:\n"
    << "  " << expr << "\n"
    << "Dependency loop found.";
    /* clang-format on */
    context->LG->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
                                                  e.str(), context->Backtrace);
  }

  int loopStep = 1;
  while (parent) {
    std::ostringstream e;
    e << "Loop step " << loopStep << "\n"
      << "  "
      << (parent->Content ? parent->Content->GetOriginalExpression() : expr)
      << "\n";
    context->LG->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
                                                  e.str(), parent->Backtrace);
    parent = parent->Parent;
    ++loopStep;
  }
}

cmGeneratorExpressionDAGChecker::Result
cmGeneratorExpressionDAGChecker::CheckGraph() const
{
  const cmGeneratorExpressionDAGChecker* parent = this->Parent;
  while (parent) {
    if (this->Target == parent->Target && this->Property == parent->Property) {
      return (parent == this->Parent) ? SELF_REFERENCE : CYCLIC_REFERENCE;
    }
    parent = parent->Parent;
  }
  return DAG;
}

bool cmGeneratorExpressionDAGChecker::GetTransitivePropertiesOnly()
{
  const cmGeneratorExpressionDAGChecker* top = this;
  const cmGeneratorExpressionDAGChecker* parent = this->Parent;
  while (parent) {
    top = parent;
    parent = parent->Parent;
  }

  return top->TransitivePropertiesOnly;
}

bool cmGeneratorExpressionDAGChecker::EvaluatingGenexExpression()
{
  return this->Property.find("TARGET_GENEX_EVAL:") == 0 ||
    this->Property.find("GENEX_EVAL:", 0) == 0;
}

bool cmGeneratorExpressionDAGChecker::EvaluatingPICExpression()
{
  const cmGeneratorExpressionDAGChecker* top = this;
  const cmGeneratorExpressionDAGChecker* parent = this->Parent;
  while (parent) {
    top = parent;
    parent = parent->Parent;
  }

  return top->Property == "INTERFACE_POSITION_INDEPENDENT_CODE";
}

bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(
  cmGeneratorTarget const* tgt)
{
  const cmGeneratorExpressionDAGChecker* top = this;
  const cmGeneratorExpressionDAGChecker* parent = this->Parent;
  while (parent) {
    top = parent;
    parent = parent->Parent;
  }

  const char* prop = top->Property.c_str();

  if (tgt) {
    return top->Target == tgt && strcmp(prop, "LINK_LIBRARIES") == 0;
  }

  return (strcmp(prop, "LINK_LIBRARIES") == 0 ||
          strcmp(prop, "LINK_INTERFACE_LIBRARIES") == 0 ||
          strcmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES") == 0 ||
          cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES_") ||
          cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_")) ||
    strcmp(prop, "INTERFACE_LINK_LIBRARIES") == 0;
}

cmGeneratorTarget const* cmGeneratorExpressionDAGChecker::TopTarget() const
{
  const cmGeneratorExpressionDAGChecker* top = this;
  const cmGeneratorExpressionDAGChecker* parent = this->Parent;
  while (parent) {
    top = parent;
    parent = parent->Parent;
  }
  return top->Target;
}

enum TransitiveProperty
{
#define DEFINE_ENUM_ENTRY(NAME) NAME,
  CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(DEFINE_ENUM_ENTRY)
#undef DEFINE_ENUM_ENTRY
    TransitivePropertyTerminal
};

template <TransitiveProperty>
bool additionalTest(const char* const /*unused*/)
{
  return false;
}

template <>
bool additionalTest<COMPILE_DEFINITIONS>(const char* const prop)
{
  return cmHasLiteralPrefix(prop, "COMPILE_DEFINITIONS_");
}

#define DEFINE_TRANSITIVE_PROPERTY_METHOD(METHOD, PROPERTY)                   \
  bool cmGeneratorExpressionDAGChecker::METHOD() const                        \
  {                                                                           \
    const char* const prop = this->Property.c_str();                          \
    if (strcmp(prop, #PROPERTY) == 0 ||                                       \
        strcmp(prop, "INTERFACE_" #PROPERTY) == 0) {                          \
      return true;                                                            \
    }                                                                         \
    return additionalTest<PROPERTY>(prop);                                    \
  }

CM_FOR_EACH_TRANSITIVE_PROPERTY(DEFINE_TRANSITIVE_PROPERTY_METHOD)

#undef DEFINE_TRANSITIVE_PROPERTY_METHOD
