/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  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 "cmGraphVizWriter.h"
#include "cmMakefile.h"
#include "cmLocalGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmGeneratedFileStream.h"



static const char* getShapeForTarget(const cmGeneratorTarget* target)
{
  if (!target)
    {
    return "ellipse";
    }

  switch ( target->GetType() )
    {
    case cmState::EXECUTABLE:
      return "house";
    case cmState::STATIC_LIBRARY:
      return "diamond";
    case cmState::SHARED_LIBRARY:
      return "polygon";
    case cmState::MODULE_LIBRARY:
      return "octagon";
    default:
      break;
    }

  return "box";
}


cmGraphVizWriter::cmGraphVizWriter(const std::vector<cmLocalGenerator*>&
                                                               localGenerators)
:GraphType("digraph")
,GraphName("GG")
,GraphHeader("node [\n  fontsize = \"12\"\n];")
,GraphNodePrefix("node")
,LocalGenerators(localGenerators)
,GenerateForExecutables(true)
,GenerateForStaticLibs(true)
,GenerateForSharedLibs(true)
,GenerateForModuleLibs(true)
,GenerateForExternals(true)
,GeneratePerTarget(true)
,GenerateDependers(true)
,HaveTargetsAndLibs(false)
{
}


void cmGraphVizWriter::ReadSettings(const char* settingsFileName,
                                    const char* fallbackSettingsFileName)
{
  cmake cm;
  cm.SetHomeDirectory("");
  cm.SetHomeOutputDirectory("");
  cm.GetCurrentSnapshot().SetDefaultDefinitions();
  cmGlobalGenerator ggi(&cm);
  cmsys::auto_ptr<cmMakefile> mf(
        new cmMakefile(&ggi, cm.GetCurrentSnapshot()));
  cmsys::auto_ptr<cmLocalGenerator> lg(ggi.CreateLocalGenerator(mf.get()));

  const char* inFileName = settingsFileName;

  if ( !cmSystemTools::FileExists(inFileName) )
    {
    inFileName = fallbackSettingsFileName;
    if ( !cmSystemTools::FileExists(inFileName) )
      {
      return;
      }
    }

  if ( !mf->ReadListFile(inFileName) )
    {
    cmSystemTools::Error("Problem opening GraphViz options file: ",
                         inFileName);
    return;
    }

  std::cout << "Reading GraphViz options file: " << inFileName << std::endl;

#define __set_if_set(var, cmakeDefinition) \
  { \
  const char* value = mf->GetDefinition(cmakeDefinition); \
  if ( value ) \
    { \
    var = value; \
    } \
  }

  __set_if_set(this->GraphType, "GRAPHVIZ_GRAPH_TYPE");
  __set_if_set(this->GraphName, "GRAPHVIZ_GRAPH_NAME");
  __set_if_set(this->GraphHeader, "GRAPHVIZ_GRAPH_HEADER");
  __set_if_set(this->GraphNodePrefix, "GRAPHVIZ_NODE_PREFIX");

#define __set_bool_if_set(var, cmakeDefinition) \
  { \
  const char* value = mf->GetDefinition(cmakeDefinition); \
  if ( value ) \
    { \
    var = mf->IsOn(cmakeDefinition); \
    } \
  }

  __set_bool_if_set(this->GenerateForExecutables, "GRAPHVIZ_EXECUTABLES");
  __set_bool_if_set(this->GenerateForStaticLibs, "GRAPHVIZ_STATIC_LIBS");
  __set_bool_if_set(this->GenerateForSharedLibs, "GRAPHVIZ_SHARED_LIBS");
  __set_bool_if_set(this->GenerateForModuleLibs, "GRAPHVIZ_MODULE_LIBS");
  __set_bool_if_set(this->GenerateForExternals, "GRAPHVIZ_EXTERNAL_LIBS");
  __set_bool_if_set(this->GeneratePerTarget, "GRAPHVIZ_GENERATE_PER_TARGET");
  __set_bool_if_set(this->GenerateDependers, "GRAPHVIZ_GENERATE_DEPENDERS");

  std::string ignoreTargetsRegexes;
  __set_if_set(ignoreTargetsRegexes, "GRAPHVIZ_IGNORE_TARGETS");

  this->TargetsToIgnoreRegex.clear();
  if (!ignoreTargetsRegexes.empty())
    {
    std::vector<std::string> ignoreTargetsRegExVector;
    cmSystemTools::ExpandListArgument(ignoreTargetsRegexes,
                                      ignoreTargetsRegExVector);
    for(std::vector<std::string>::const_iterator itvIt
                                            = ignoreTargetsRegExVector.begin();
        itvIt != ignoreTargetsRegExVector.end();
        ++ itvIt )
      {
      std::string currentRegexString(*itvIt);
      cmsys::RegularExpression currentRegex;
      if (!currentRegex.compile(currentRegexString.c_str()))
        {
        std::cerr << "Could not compile bad regex \"" << currentRegexString
                  << "\"" << std::endl;
        }
      this->TargetsToIgnoreRegex.push_back(currentRegex);
      }
    }

}


// Iterate over all targets and write for each one a graph which shows
// which other targets depend on it.
void cmGraphVizWriter::WriteTargetDependersFiles(const char* fileName)
{
  if(this->GenerateDependers == false)
    {
    return;
    }

  this->CollectTargetsAndLibs();

  for(std::map<std::string, const cmGeneratorTarget*>::const_iterator ptrIt =
                                                      this->TargetPtrs.begin();
      ptrIt != this->TargetPtrs.end();
      ++ptrIt)
    {
    if (ptrIt->second == NULL)
      {
      continue;
      }

    if (this->GenerateForTargetType(ptrIt->second->GetType()) == false)
      {
      continue;
      }

    std::string currentFilename = fileName;
    currentFilename += ".";
    currentFilename += ptrIt->first;
    currentFilename += ".dependers";

    cmGeneratedFileStream str(currentFilename.c_str());
    if ( !str )
      {
      return;
      }

    std::set<std::string> insertedConnections;
    std::set<std::string> insertedNodes;

    std::cout << "Writing " << currentFilename << "..." << std::endl;
    this->WriteHeader(str);

    this->WriteDependerConnections(ptrIt->first,
                                   insertedNodes, insertedConnections, str);

    this->WriteFooter(str);
    }
}


// Iterate over all targets and write for each one a graph which shows
// on which targets it depends.
void cmGraphVizWriter::WritePerTargetFiles(const char* fileName)
{
  if(this->GeneratePerTarget == false)
    {
    return;
    }

  this->CollectTargetsAndLibs();

  for(std::map<std::string, const cmGeneratorTarget*>::const_iterator ptrIt =
                                                      this->TargetPtrs.begin();
      ptrIt != this->TargetPtrs.end();
      ++ptrIt)
    {
    if (ptrIt->second == NULL)
      {
      continue;
      }

    if (this->GenerateForTargetType(ptrIt->second->GetType()) == false)
      {
      continue;
      }

    std::set<std::string> insertedConnections;
    std::set<std::string> insertedNodes;

    std::string currentFilename = fileName;
    currentFilename += ".";
    currentFilename += ptrIt->first;
    cmGeneratedFileStream str(currentFilename.c_str());
    if ( !str )
      {
      return;
      }

    std::cout << "Writing " << currentFilename << "..." << std::endl;
    this->WriteHeader(str);

    this->WriteConnections(ptrIt->first,
                              insertedNodes, insertedConnections, str);
    this->WriteFooter(str);
    }

}


void cmGraphVizWriter::WriteGlobalFile(const char* fileName)
{
  this->CollectTargetsAndLibs();

  cmGeneratedFileStream str(fileName);
  if ( !str )
    {
    return;
    }
  this->WriteHeader(str);

  std::cout << "Writing " << fileName << "..." << std::endl;

  std::set<std::string> insertedConnections;
  std::set<std::string> insertedNodes;

  for(std::map<std::string, const cmGeneratorTarget*>::const_iterator ptrIt =
                                                      this->TargetPtrs.begin();
      ptrIt != this->TargetPtrs.end();
      ++ptrIt)
    {
    if (ptrIt->second == NULL)
      {
      continue;
      }

    if (this->GenerateForTargetType(ptrIt->second->GetType()) == false)
      {
      continue;
      }

    this->WriteConnections(ptrIt->first,
                              insertedNodes, insertedConnections, str);
    }
  this->WriteFooter(str);
}


void cmGraphVizWriter::WriteHeader(cmGeneratedFileStream& str) const
{
  str << this->GraphType << " \"" << this->GraphName << "\" {" << std::endl;
  str << this->GraphHeader << std::endl;
}


void cmGraphVizWriter::WriteFooter(cmGeneratedFileStream& str) const
{
  str << "}" << std::endl;
}


void cmGraphVizWriter::WriteConnections(const std::string& targetName,
                                    std::set<std::string>& insertedNodes,
                                    std::set<std::string>& insertedConnections,
                                    cmGeneratedFileStream& str) const
{
  std::map<std::string, const cmGeneratorTarget* >::const_iterator targetPtrIt
      = this->TargetPtrs.find(targetName);

  if (targetPtrIt == this->TargetPtrs.end())  // not found at all
    {
    return;
    }

  this->WriteNode(targetName, targetPtrIt->second, insertedNodes, str);

  if (targetPtrIt->second == NULL) // it's an external library
    {
    return;
    }


  std::string myNodeName = this->TargetNamesNodes.find(targetName)->second;

  const cmTarget::LinkLibraryVectorType* ll =
      &(targetPtrIt->second->Target->GetOriginalLinkLibraries());

  for (cmTarget::LinkLibraryVectorType::const_iterator llit = ll->begin();
       llit != ll->end();
       ++ llit )
    {
    const char* libName = llit->first.c_str();
    std::map<std::string, std::string>::const_iterator libNameIt =
                                          this->TargetNamesNodes.find(libName);

    // can happen e.g. if GRAPHVIZ_TARGET_IGNORE_REGEX is used
    if(libNameIt == this->TargetNamesNodes.end())
      {
      continue;
      }

    std::string connectionName = myNodeName;
    connectionName += "-";
    connectionName += libNameIt->second;
    if (insertedConnections.find(connectionName) == insertedConnections.end())
      {
      insertedConnections.insert(connectionName);
      this->WriteNode(libName, this->TargetPtrs.find(libName)->second,
                      insertedNodes, str);

      str << "    \"" << myNodeName << "\" -> \""
          << libNameIt->second << "\"";
      str << " // " << targetName << " -> " << libName << std::endl;
      this->WriteConnections(libName, insertedNodes, insertedConnections, str);
      }
    }

}


void cmGraphVizWriter::WriteDependerConnections(const std::string& targetName,
                                    std::set<std::string>& insertedNodes,
                                    std::set<std::string>& insertedConnections,
                                    cmGeneratedFileStream& str) const
{
  std::map<std::string, const cmGeneratorTarget* >::const_iterator targetPtrIt
      = this->TargetPtrs.find(targetName);

  if (targetPtrIt == this->TargetPtrs.end())  // not found at all
    {
    return;
    }

  this->WriteNode(targetName, targetPtrIt->second, insertedNodes, str);

  if (targetPtrIt->second == NULL) // it's an external library
    {
    return;
    }


  std::string myNodeName = this->TargetNamesNodes.find(targetName)->second;

  // now search who links against me
  for(std::map<std::string, const cmGeneratorTarget*>::const_iterator
      dependerIt = this->TargetPtrs.begin();
      dependerIt != this->TargetPtrs.end();
      ++dependerIt)
    {
    if (dependerIt->second == NULL)
      {
      continue;
      }

    if (this->GenerateForTargetType(dependerIt->second->GetType()) == false)
      {
      continue;
      }

    // Now we have a target, check whether it links against targetName.
    // If so, draw a connection, and then continue with dependers on that one.
    const cmTarget::LinkLibraryVectorType* ll =
        &(dependerIt->second->Target->GetOriginalLinkLibraries());

    for (cmTarget::LinkLibraryVectorType::const_iterator llit = ll->begin();
         llit != ll->end();
         ++ llit )
      {
      std::string libName = llit->first;
      if (libName == targetName)
        {
        // So this target links against targetName.
        std::map<std::string, std::string>::const_iterator dependerNodeNameIt =
                                this->TargetNamesNodes.find(dependerIt->first);

        if(dependerNodeNameIt != this->TargetNamesNodes.end())
          {
          std::string connectionName = dependerNodeNameIt->second;
          connectionName += "-";
          connectionName += myNodeName;

          if (insertedConnections.find(connectionName) ==
                                                     insertedConnections.end())
            {
            insertedConnections.insert(connectionName);
            this->WriteNode(dependerIt->first, dependerIt->second,
                            insertedNodes, str);

            str << "    \"" << dependerNodeNameIt->second << "\" -> \""
                << myNodeName << "\"";
            str << " // " <<targetName<< " -> " <<dependerIt->first<<std::endl;
            this->WriteDependerConnections(dependerIt->first,
                                      insertedNodes, insertedConnections, str);
            }


          }
        break;
        }
      }
    }

}


void cmGraphVizWriter::WriteNode(const std::string& targetName,
                                 const cmGeneratorTarget* target,
                                 std::set<std::string>& insertedNodes,
                                 cmGeneratedFileStream& str) const
{
  if (insertedNodes.find(targetName) == insertedNodes.end())
  {
    insertedNodes.insert(targetName);
    std::map<std::string, std::string>::const_iterator nameIt =
                                       this->TargetNamesNodes.find(targetName);

    str << "    \"" << nameIt->second << "\" [ label=\""
        << targetName <<  "\" shape=\"" << getShapeForTarget(target)
        << "\"];" << std::endl;
  }
}


void cmGraphVizWriter::CollectTargetsAndLibs()
{
  if (this->HaveTargetsAndLibs == false)
    {
    this->HaveTargetsAndLibs = true;
    int cnt = this->CollectAllTargets();
    if (this->GenerateForExternals)
      {
      this->CollectAllExternalLibs(cnt);
      }
    }
}


int cmGraphVizWriter::CollectAllTargets()
{
  int cnt = 0;
  // First pass get the list of all cmake targets
  for (std::vector<cmLocalGenerator*>::const_iterator lit =
                                                 this->LocalGenerators.begin();
       lit != this->LocalGenerators.end();
       ++ lit )
    {
    std::vector<cmGeneratorTarget*> targets = (*lit)->GetGeneratorTargets();
    for ( std::vector<cmGeneratorTarget*>::const_iterator it =
          targets.begin(); it != targets.end(); ++it )
      {
      const char* realTargetName = (*it)->GetName().c_str();
      if(this->IgnoreThisTarget(realTargetName))
        {
        // Skip ignored targets
        continue;
        }
      //std::cout << "Found target: " << tit->first.c_str() << std::endl;
      std::ostringstream ostr;
      ostr << this->GraphNodePrefix << cnt++;
      this->TargetNamesNodes[realTargetName] = ostr.str();
      this->TargetPtrs[realTargetName] = *it;
      }
    }

  return cnt;
}


int cmGraphVizWriter::CollectAllExternalLibs(int cnt)
{
  // Ok, now find all the stuff we link to that is not in cmake
  for (std::vector<cmLocalGenerator*>::const_iterator lit =
                                                 this->LocalGenerators.begin();
       lit != this->LocalGenerators.end();
       ++ lit )
    {
    std::vector<cmGeneratorTarget*> targets = (*lit)->GetGeneratorTargets();
    for ( std::vector<cmGeneratorTarget*>::const_iterator it =
          targets.begin(); it != targets.end(); ++it )
      {
      const char* realTargetName = (*it)->GetName().c_str();
      if (this->IgnoreThisTarget(realTargetName))
        {
        // Skip ignored targets
        continue;
        }
      const cmTarget::LinkLibraryVectorType* ll =
          &((*it)->Target->GetOriginalLinkLibraries());
      for (cmTarget::LinkLibraryVectorType::const_iterator llit = ll->begin();
           llit != ll->end();
           ++ llit )
        {
        const char* libName = llit->first.c_str();
        if (this->IgnoreThisTarget(libName))
          {
          // Skip ignored targets
          continue;
          }

        std::map<std::string, const cmGeneratorTarget*>::const_iterator tarIt
            = this->TargetPtrs.find(libName);
        if ( tarIt == this->TargetPtrs.end() )
          {
          std::ostringstream ostr;
          ostr << this->GraphNodePrefix << cnt++;
          this->TargetNamesNodes[libName] = ostr.str();
          this->TargetPtrs[libName] = NULL;
          // str << "    \"" << ostr.c_str() << "\" [ label=\"" << libName
          // <<  "\" shape=\"ellipse\"];" << std::endl;
          }
        }
      }
    }
   return cnt;
}


bool cmGraphVizWriter::IgnoreThisTarget(const std::string& name)
{
  for(std::vector<cmsys::RegularExpression>::iterator itvIt
                                          = this->TargetsToIgnoreRegex.begin();
      itvIt != this->TargetsToIgnoreRegex.end();
      ++ itvIt )
    {
    cmsys::RegularExpression& regEx = *itvIt;
    if (regEx.is_valid())
      {
      if (regEx.find(name))
        {
        return true;
        }
      }
    }

  return false;
}


bool cmGraphVizWriter::GenerateForTargetType(cmState::TargetType targetType)
                                                                          const
{
  switch (targetType)
  {
    case cmState::EXECUTABLE:
      return this->GenerateForExecutables;
    case cmState::STATIC_LIBRARY:
      return this->GenerateForStaticLibs;
    case cmState::SHARED_LIBRARY:
      return this->GenerateForSharedLibs;
    case cmState::MODULE_LIBRARY:
      return this->GenerateForModuleLibs;
    default:
      break;
  }
  return false;
}
