//===--- CompilationGraph.cpp - The LLVM Compiler Driver --------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open
// Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  Compilation graph - implementation.
//
//===----------------------------------------------------------------------===//

#include "llvm/CompilerDriver/BuiltinOptions.h"
#include "llvm/CompilerDriver/CompilationGraph.h"
#include "llvm/CompilerDriver/Error.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/DOTGraphTraits.h"
#include "llvm/Support/GraphWriter.h"
#include "llvm/Support/raw_ostream.h"

#include <algorithm>
#include <cstring>
#include <iterator>
#include <limits>
#include <queue>

using namespace llvm;
using namespace llvmc;

namespace llvmc {

  const std::string* LanguageMap::GetLanguage(const sys::Path& File) const {
    StringRef suf = File.getSuffix();
    LanguageMap::const_iterator Lang =
      this->find(suf.empty() ? "*empty*" : suf);
    if (Lang == this->end()) {
      PrintError("File '" + File.str() + "' has unknown suffix '"
                 + suf.str() + '\'');
      return 0;
    }
    return &Lang->second;
  }
}

namespace {

  /// ChooseEdge - Return the edge with the maximum weight. Returns 0 on error.
  template <class C>
  const Edge* ChooseEdge(const C& EdgesContainer,
                         const InputLanguagesSet& InLangs,
                         const std::string& NodeName = "root") {
    const Edge* MaxEdge = 0;
    int MaxWeight = 0;
    bool SingleMax = true;

    // TODO: fix calculation of SingleMax.
    for (typename C::const_iterator B = EdgesContainer.begin(),
           E = EdgesContainer.end(); B != E; ++B) {
      const Edge* e = B->getPtr();
      int EW = e->Weight(InLangs);
      if (EW < 0) {
        // (error) invocation in TableGen -> we don't need to print an error
        // message.
        return 0;
      }
      if (EW > MaxWeight) {
        MaxEdge = e;
        MaxWeight = EW;
        SingleMax = true;
      } else if (EW == MaxWeight) {
        SingleMax = false;
      }
    }

    if (!SingleMax) {
      PrintError("Node " + NodeName + ": multiple maximal outward edges found!"
                 " Most probably a specification error.");
      return 0;
    }
    if (!MaxEdge) {
      PrintError("Node " + NodeName + ": no maximal outward edge found!"
                 " Most probably a specification error.");
      return 0;
    }
    return MaxEdge;
  }

}

void Node::AddEdge(Edge* Edg) {
  // If there already was an edge between two nodes, modify it instead
  // of adding a new edge.
  const std::string& ToolName = Edg->ToolName();
  for (container_type::iterator B = OutEdges.begin(), E = OutEdges.end();
       B != E; ++B) {
    if ((*B)->ToolName() == ToolName) {
      llvm::IntrusiveRefCntPtr<Edge>(Edg).swap(*B);
      return;
    }
  }
  OutEdges.push_back(llvm::IntrusiveRefCntPtr<Edge>(Edg));
}

CompilationGraph::CompilationGraph() {
  NodesMap["root"] = Node(this);
}

Node* CompilationGraph::getNode(const std::string& ToolName) {
  nodes_map_type::iterator I = NodesMap.find(ToolName);
  if (I == NodesMap.end()) {
    PrintError("Node " + ToolName + " is not in the graph");
    return 0;
  }
  return &I->second;
}

const Node* CompilationGraph::getNode(const std::string& ToolName) const {
  nodes_map_type::const_iterator I = NodesMap.find(ToolName);
  if (I == NodesMap.end()) {
    PrintError("Node " + ToolName + " is not in the graph!");
    return 0;
  }
  return &I->second;
}

// Find the tools list corresponding to the given language name.
const CompilationGraph::tools_vector_type*
CompilationGraph::getToolsVector(const std::string& LangName) const
{
  tools_map_type::const_iterator I = ToolsMap.find(LangName);
  if (I == ToolsMap.end()) {
    PrintError("No tool corresponding to the language " + LangName + " found");
    return 0;
  }
  return &I->second;
}

void CompilationGraph::insertNode(Tool* V) {
  if (NodesMap.count(V->Name()) == 0)
    NodesMap[V->Name()] = Node(this, V);
}

int CompilationGraph::insertEdge(const std::string& A, Edge* Edg) {
  Node* B = getNode(Edg->ToolName());
  if (B == 0)
    return 1;

  if (A == "root") {
    const char** InLangs = B->ToolPtr->InputLanguages();
    for (;*InLangs; ++InLangs)
      ToolsMap[*InLangs].push_back(IntrusiveRefCntPtr<Edge>(Edg));
    NodesMap["root"].AddEdge(Edg);
  }
  else {
    Node* N = getNode(A);
    if (N == 0)
      return 1;

    N->AddEdge(Edg);
  }
  // Increase the inward edge counter.
  B->IncrInEdges();

  return 0;
}

// Pass input file through the chain until we bump into a Join node or
// a node that says that it is the last.
int CompilationGraph::PassThroughGraph (const sys::Path& InFile,
                                        const Node* StartNode,
                                        const InputLanguagesSet& InLangs,
                                        const sys::Path& TempDir,
                                        const LanguageMap& LangMap) const {
  sys::Path In = InFile;
  const Node* CurNode = StartNode;

  while(true) {
    Tool* CurTool = CurNode->ToolPtr.getPtr();

    if (CurTool->IsJoin()) {
      JoinTool& JT = static_cast<JoinTool&>(*CurTool);
      JT.AddToJoinList(In);
      break;
    }

    Action CurAction;
    if (int ret = CurTool->GenerateAction(CurAction, In, CurNode->HasChildren(),
                                          TempDir, InLangs, LangMap)) {
      return ret;
    }

    if (int ret = CurAction.Execute())
      return ret;

    if (CurAction.StopCompilation())
      return 0;

    const Edge* Edg = ChooseEdge(CurNode->OutEdges, InLangs, CurNode->Name());
    if (Edg == 0)
      return 1;

    CurNode = getNode(Edg->ToolName());
    if (CurNode == 0)
      return 1;

    In = CurAction.OutFile();
  }

  return 0;
}

// Find the head of the toolchain corresponding to the given file.
// Also, insert an input language into InLangs.
const Node* CompilationGraph::
FindToolChain(const sys::Path& In, const std::string* ForceLanguage,
              InputLanguagesSet& InLangs, const LanguageMap& LangMap) const {

  // Determine the input language.
  const std::string* InLang = LangMap.GetLanguage(In);
  if (InLang == 0)
    return 0;
  const std::string& InLanguage = (ForceLanguage ? *ForceLanguage : *InLang);

  // Add the current input language to the input language set.
  InLangs.insert(InLanguage);

  // Find the toolchain for the input language.
  const tools_vector_type* pTV = getToolsVector(InLanguage);
  if (pTV == 0)
    return 0;

  const tools_vector_type& TV = *pTV;
  if (TV.empty()) {
    PrintError("No toolchain corresponding to language "
               + InLanguage + " found");
    return 0;
  }

  const Edge* Edg = ChooseEdge(TV, InLangs);
  if (Edg == 0)
    return 0;

  return getNode(Edg->ToolName());
}

// Helper function used by Build().
// Traverses initial portions of the toolchains (up to the first Join node).
// This function is also responsible for handling the -x option.
int CompilationGraph::BuildInitial (InputLanguagesSet& InLangs,
                                    const sys::Path& TempDir,
                                    const LanguageMap& LangMap) {
  // This is related to -x option handling.
  cl::list<std::string>::const_iterator xIter = Languages.begin(),
    xBegin = xIter, xEnd = Languages.end();
  bool xEmpty = true;
  const std::string* xLanguage = 0;
  unsigned xPos = 0, xPosNext = 0, filePos = 0;

  if (xIter != xEnd) {
    xEmpty = false;
    xPos = Languages.getPosition(xIter - xBegin);
    cl::list<std::string>::const_iterator xNext = llvm::next(xIter);
    xPosNext = (xNext == xEnd) ? std::numeric_limits<unsigned>::max()
      : Languages.getPosition(xNext - xBegin);
    xLanguage = (*xIter == "none") ? 0 : &(*xIter);
  }

  // For each input file:
  for (cl::list<std::string>::const_iterator B = InputFilenames.begin(),
         CB = B, E = InputFilenames.end(); B != E; ++B) {
    sys::Path In = sys::Path(*B);

    // Code for handling the -x option.
    // Output: std::string* xLanguage (can be NULL).
    if (!xEmpty) {
      filePos = InputFilenames.getPosition(B - CB);

      if (xPos < filePos) {
        if (filePos < xPosNext) {
          xLanguage = (*xIter == "none") ? 0 : &(*xIter);
        }
        else { // filePos >= xPosNext
          // Skip xIters while filePos > xPosNext
          while (filePos > xPosNext) {
            ++xIter;
            xPos = xPosNext;

            cl::list<std::string>::const_iterator xNext = llvm::next(xIter);
            if (xNext == xEnd)
              xPosNext = std::numeric_limits<unsigned>::max();
            else
              xPosNext = Languages.getPosition(xNext - xBegin);
            xLanguage = (*xIter == "none") ? 0 : &(*xIter);
          }
        }
      }
    }

    // Find the toolchain corresponding to this file.
    const Node* N = FindToolChain(In, xLanguage, InLangs, LangMap);
    if (N == 0)
      return 1;
    // Pass file through the chain starting at head.
    if (int ret = PassThroughGraph(In, N, InLangs, TempDir, LangMap))
      return ret;
  }

  return 0;
}

// Sort the nodes in topological order.
int CompilationGraph::TopologicalSort(std::vector<const Node*>& Out) {
  std::queue<const Node*> Q;

  Node* Root = getNode("root");
  if (Root == 0)
    return 1;

  Q.push(Root);

  while (!Q.empty()) {
    const Node* A = Q.front();
    Q.pop();
    Out.push_back(A);
    for (Node::const_iterator EB = A->EdgesBegin(), EE = A->EdgesEnd();
         EB != EE; ++EB) {
      Node* B = getNode((*EB)->ToolName());
      if (B == 0)
        return 1;

      B->DecrInEdges();
      if (B->HasNoInEdges())
        Q.push(B);
    }
  }

  return 0;
}

namespace {
  bool NotJoinNode(const Node* N) {
    return N->ToolPtr ? !N->ToolPtr->IsJoin() : true;
  }
}

// Call TopologicalSort and filter the resulting list to include
// only Join nodes.
int CompilationGraph::
TopologicalSortFilterJoinNodes(std::vector<const Node*>& Out) {
  std::vector<const Node*> TopSorted;
  if (int ret = TopologicalSort(TopSorted))
    return ret;
  std::remove_copy_if(TopSorted.begin(), TopSorted.end(),
                      std::back_inserter(Out), NotJoinNode);

  return 0;
}

int CompilationGraph::Build (const sys::Path& TempDir,
                             const LanguageMap& LangMap) {
  InputLanguagesSet InLangs;
  bool WasSomeActionGenerated = !InputFilenames.empty();

  // Traverse initial parts of the toolchains and fill in InLangs.
  if (int ret = BuildInitial(InLangs, TempDir, LangMap))
    return ret;

  std::vector<const Node*> JTV;
  if (int ret = TopologicalSortFilterJoinNodes(JTV))
    return ret;

  // For all join nodes in topological order:
  for (std::vector<const Node*>::iterator B = JTV.begin(), E = JTV.end();
       B != E; ++B) {

    const Node* CurNode = *B;
    JoinTool* JT = &static_cast<JoinTool&>(*CurNode->ToolPtr.getPtr());

    // Are there any files in the join list?
    if (JT->JoinListEmpty() && !(JT->WorksOnEmpty() && InputFilenames.empty()))
      continue;

    WasSomeActionGenerated = true;
    Action CurAction;
    if (int ret = JT->GenerateAction(CurAction, CurNode->HasChildren(),
                                     TempDir, InLangs, LangMap)) {
      return ret;
    }

    if (int ret = CurAction.Execute())
      return ret;

    if (CurAction.StopCompilation())
      return 0;

    const Edge* Edg = ChooseEdge(CurNode->OutEdges, InLangs, CurNode->Name());
    if (Edg == 0)
      return 1;

    const Node* NextNode = getNode(Edg->ToolName());
    if (NextNode == 0)
      return 1;

    if (int ret = PassThroughGraph(sys::Path(CurAction.OutFile()), NextNode,
                                   InLangs, TempDir, LangMap)) {
      return ret;
    }
  }

  if (!WasSomeActionGenerated) {
    PrintError("no input files");
    return 1;
  }

  return 0;
}

int CompilationGraph::CheckLanguageNames() const {
  int ret = 0;

  // Check that names for output and input languages on all edges do match.
  for (const_nodes_iterator B = this->NodesMap.begin(),
         E = this->NodesMap.end(); B != E; ++B) {

    const Node & N1 = B->second;
    if (N1.ToolPtr) {
      for (Node::const_iterator EB = N1.EdgesBegin(), EE = N1.EdgesEnd();
           EB != EE; ++EB) {
        const Node* N2 = this->getNode((*EB)->ToolName());
        if (N2 == 0)
          return 1;

        if (!N2->ToolPtr) {
          ++ret;
          errs() << "Error: there is an edge from '" << N1.ToolPtr->Name()
                 << "' back to the root!\n\n";
          continue;
        }

        const char* OutLang = N1.ToolPtr->OutputLanguage();
        const char** InLangs = N2->ToolPtr->InputLanguages();
        bool eq = false;
        for (;*InLangs; ++InLangs) {
          if (std::strcmp(OutLang, *InLangs) == 0) {
            eq = true;
            break;
          }
        }

        if (!eq) {
          ++ret;
          errs() << "Error: Output->input language mismatch in the edge '"
                 << N1.ToolPtr->Name() << "' -> '" << N2->ToolPtr->Name()
                 << "'!\n"
                 << "Expected one of { ";

          InLangs = N2->ToolPtr->InputLanguages();
          for (;*InLangs; ++InLangs) {
            errs() << '\'' << *InLangs << (*(InLangs+1) ? "', " : "'");
          }

          errs() << " }, but got '" << OutLang << "'!\n\n";
        }

      }
    }
  }

  return ret;
}

int CompilationGraph::CheckMultipleDefaultEdges() const {
  int ret = 0;
  InputLanguagesSet Dummy;

  // For all nodes, just iterate over the outgoing edges and check if there is
  // more than one edge with maximum weight.
  for (const_nodes_iterator B = this->NodesMap.begin(),
         E = this->NodesMap.end(); B != E; ++B) {
    const Node& N = B->second;
    int MaxWeight = 0;

    // Ignore the root node.
    if (!N.ToolPtr)
      continue;

    for (Node::const_iterator EB = N.EdgesBegin(), EE = N.EdgesEnd();
         EB != EE; ++EB) {
      int EdgeWeight = (*EB)->Weight(Dummy);
      if (EdgeWeight > MaxWeight) {
        MaxWeight = EdgeWeight;
      }
      else if (EdgeWeight == MaxWeight) {
        ++ret;
        errs() << "Error: there are multiple maximal edges stemming from the '"
               << N.ToolPtr->Name() << "' node!\n\n";
        break;
      }
    }
  }

  return ret;
}

int CompilationGraph::CheckCycles() {
  unsigned deleted = 0;
  std::queue<Node*> Q;

  Node* Root = getNode("root");
  if (Root == 0)
    return 1;

  Q.push(Root);

  // Try to delete all nodes that have no ingoing edges, starting from the
  // root. If there are any nodes left after this operation, then we have a
  // cycle. This relies on '--check-graph' not performing the topological sort.
  while (!Q.empty()) {
    Node* A = Q.front();
    Q.pop();
    ++deleted;

    for (Node::iterator EB = A->EdgesBegin(), EE = A->EdgesEnd();
         EB != EE; ++EB) {
      Node* B = getNode((*EB)->ToolName());
      if (B == 0)
        return 1;

      B->DecrInEdges();
      if (B->HasNoInEdges())
        Q.push(B);
    }
  }

  if (deleted != NodesMap.size()) {
    errs() << "Error: there are cycles in the compilation graph!\n"
           << "Try inspecting the diagram produced by "
           << "'llvmc --view-graph'.\n\n";
    return 1;
  }

  return 0;
}

int CompilationGraph::Check () {
  // We try to catch as many errors as we can in one go.
  int errs = 0;
  int ret = 0;

  // Check that output/input language names match.
  ret = this->CheckLanguageNames();
  if (ret < 0)
    return 1;
  errs += ret;

  // Check for multiple default edges.
  ret = this->CheckMultipleDefaultEdges();
  if (ret < 0)
    return 1;
  errs += ret;

  // Check for cycles.
  ret = this->CheckCycles();
  if (ret < 0)
    return 1;
  errs += ret;

  return errs;
}

// Code related to graph visualization.

namespace llvm {
  template <>
  struct DOTGraphTraits<llvmc::CompilationGraph*>
    : public DefaultDOTGraphTraits
  {
    DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}

    template<typename GraphType>
    static std::string getNodeLabel(const Node* N, const GraphType&)
    {
      if (N->ToolPtr)
        if (N->ToolPtr->IsJoin())
          return N->Name() + "\n (join" +
            (N->HasChildren() ? ")"
             : std::string(": ") + N->ToolPtr->OutputLanguage() + ')');
        else
          return N->Name();
      else
        return "root";
    }

    template<typename EdgeIter>
    static std::string getEdgeSourceLabel(const Node* N, EdgeIter I) {
      if (N->ToolPtr) {
        return N->ToolPtr->OutputLanguage();
      }
      else {
        const char** InLangs = I->ToolPtr->InputLanguages();
        std::string ret;

        for (; *InLangs; ++InLangs) {
          if (*(InLangs + 1)) {
            ret += *InLangs;
            ret +=  ", ";
          }
          else {
            ret += *InLangs;
          }
        }

        return ret;
      }
    }
  };

}

int CompilationGraph::writeGraph(const std::string& OutputFilename) {
  std::string ErrorInfo;
  raw_fd_ostream O(OutputFilename.c_str(), ErrorInfo);

  if (ErrorInfo.empty()) {
    errs() << "Writing '"<< OutputFilename << "' file...";
    llvm::WriteGraph(O, this);
    errs() << "done.\n";
  }
  else {
    PrintError("Error opening file '" + OutputFilename + "' for writing!");
    return 1;
  }

  return 0;
}

void CompilationGraph::viewGraph() {
  llvm::ViewGraph(this, "compilation-graph");
}
