/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2012 Stephen Kelly <steveire@gmail.com>

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/

#include "cmGeneratorExpressionDAGChecker.h"

#include "cmMakefile.h"
#include "cmAlgorithms.h"

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

//----------------------------------------------------------------------------
cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
                const std::string &target,
                const std::string &property,
                const GeneratorExpressionContent *content,
                cmGeneratorExpressionDAGChecker *parent)
  : Parent(parent), Target(target), Property(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)
     )
#undef TEST_TRANSITIVE_PROPERTY_METHOD
    {
    std::map<std::string, 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->Makefile->GetCMakeInstance()
      ->IssueMessage(cmake::FATAL_ERROR, e.str(),
                      parent->Backtrace);
    return;
    }

  {
  std::ostringstream e;
  e << "Error evaluating generator expression:\n"
    << "  " << expr << "\n"
    << "Dependency loop found.";
  context->Makefile->GetCMakeInstance()
    ->IssueMessage(cmake::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->Makefile->GetCMakeInstance()
      ->IssueMessage(cmake::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::EvaluatingLinkLibraries(const char *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;
}

std::string 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)
{
  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
