﻿/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
 * Use of this file is governed by the BSD 3-clause license that
 * can be found in the LICENSE.txt file in the project root.
 */

#include "tree/ErrorNode.h"
#include "Parser.h"
#include "ParserRuleContext.h"
#include "support/CPPUtils.h"
#include "tree/TerminalNodeImpl.h"
#include "atn/ATN.h"
#include "misc/Interval.h"
#include "Token.h"
#include "CommonToken.h"
#include "misc/Predicate.h"

#include "tree/Trees.h"

using namespace antlr4;
using namespace antlr4::misc;
using namespace antlr4::tree;

using namespace antlrcpp;

Trees::Trees() {
}

std::string Trees::toStringTree(ParseTree *t, bool pretty) {
  return toStringTree(t, nullptr, pretty);
}

std::string Trees::toStringTree(ParseTree *t, Parser *recog, bool pretty) {
  if (recog == nullptr)
    return toStringTree(t, std::vector<std::string>(), pretty);
  return toStringTree(t, recog->getRuleNames(), pretty);
}

std::string Trees::toStringTree(ParseTree *t, const std::vector<std::string> &ruleNames, bool pretty) {
  std::string temp = antlrcpp::escapeWhitespace(Trees::getNodeText(t, ruleNames), false);
  if (t->children.empty()) {
    return temp;
  }

  std::stringstream ss;
  ss << "(" << temp << ' ';

  // Implement the recursive walk as iteration to avoid trouble with deep nesting.
  std::stack<size_t> stack;
  size_t childIndex = 0;
  ParseTree *run = t;
  size_t indentationLevel = 1;
  while (childIndex < run->children.size()) {
    if (childIndex > 0) {
      ss << ' ';
    }
    ParseTree *child = run->children[childIndex];
    temp = antlrcpp::escapeWhitespace(Trees::getNodeText(child, ruleNames), false);
    if (!child->children.empty()) {
      // Go deeper one level.
      stack.push(childIndex);
      run = child;
      childIndex = 0;
      if (pretty) {
        ++indentationLevel;
        ss << std::endl;
        for (size_t i = 0; i < indentationLevel; ++i) {
          ss << "    ";
        }
      }
      ss << "(" << temp << " ";
    } else {
      ss << temp;
      while (++childIndex == run->children.size()) {
        if (stack.size() > 0) {
          // Reached the end of the current level. See if we can step up from here.
          childIndex = stack.top();
          stack.pop();
          run = run->parent;
          if (pretty) {
            --indentationLevel;
          }
          ss << ")";
        } else {
          break;
        }
      }
    }
  }

  ss << ")";
  return ss.str();
}

std::string Trees::getNodeText(ParseTree *t, Parser *recog) {
  return getNodeText(t, recog->getRuleNames());
}

std::string Trees::getNodeText(ParseTree *t, const std::vector<std::string> &ruleNames) {
  if (ruleNames.size() > 0) {
    if (is<RuleContext *>(t)) {
      size_t ruleIndex = dynamic_cast<RuleContext *>(t)->getRuleIndex();
      std::string ruleName = ruleNames[ruleIndex];
      size_t altNumber = dynamic_cast<RuleContext *>(t)->getAltNumber();
      if (altNumber != atn::ATN::INVALID_ALT_NUMBER) {
        return ruleName + ":" + std::to_string(altNumber);
      }
      return ruleName;
    } else if (is<ErrorNode *>(t)) {
      return t->toString();
    } else if (is<TerminalNode *>(t)) {
      Token *symbol = dynamic_cast<TerminalNode *>(t)->getSymbol();
      if (symbol != nullptr) {
        std::string s = symbol->getText();
        return s;
      }
    }
  }
  // no recog for rule names
  if (is<RuleContext *>(t)) {
    return dynamic_cast<RuleContext *>(t)->getText();
  }

  if (is<TerminalNodeImpl *>(t)) {
    return dynamic_cast<TerminalNodeImpl *>(t)->getSymbol()->getText();
  }

  return "";
}

std::vector<ParseTree *> Trees::getAncestors(ParseTree *t) {
  std::vector<ParseTree *> ancestors;
  ParseTree *parent = t->parent;
  while (parent != nullptr) {
    ancestors.insert(ancestors.begin(), parent); // insert at start
    parent = parent->parent;
  }
  return ancestors;
}

template<typename T>
static void _findAllNodes(ParseTree *t, size_t index, bool findTokens, std::vector<T> &nodes) {
  // check this node (the root) first
  if (findTokens && is<TerminalNode *>(t)) {
    TerminalNode *tnode = dynamic_cast<TerminalNode *>(t);
    if (tnode->getSymbol()->getType() == index) {
      nodes.push_back(t);
    }
  } else if (!findTokens && is<ParserRuleContext *>(t)) {
    ParserRuleContext *ctx = dynamic_cast<ParserRuleContext *>(t);
    if (ctx->getRuleIndex() == index) {
      nodes.push_back(t);
    }
  }
  // check children
  for (size_t i = 0; i < t->children.size(); i++) {
    _findAllNodes(t->children[i], index, findTokens, nodes);
  }
}

bool Trees::isAncestorOf(ParseTree *t, ParseTree *u) {
  if (t == nullptr || u == nullptr || t->parent == nullptr) {
    return false;
  }

  ParseTree *p = u->parent;
  while (p != nullptr) {
    if (t == p) {
      return true;
    }
    p = p->parent;
  }
  return false;
}

std::vector<ParseTree *> Trees::findAllTokenNodes(ParseTree *t, size_t ttype) {
  return findAllNodes(t, ttype, true);
}

std::vector<ParseTree *> Trees::findAllRuleNodes(ParseTree *t, size_t ruleIndex) {
  return findAllNodes(t, ruleIndex, false);
}

std::vector<ParseTree *> Trees::findAllNodes(ParseTree *t, size_t index, bool findTokens) {
  std::vector<ParseTree *> nodes;
  _findAllNodes<ParseTree *>(t, index, findTokens, nodes);
  return nodes;
}

std::vector<ParseTree *> Trees::getDescendants(ParseTree *t) {
  std::vector<ParseTree *> nodes;
  nodes.push_back(t);
  std::size_t n = t->children.size();
  for (size_t i = 0 ; i < n ; i++) {
    auto descentants = getDescendants(t->children[i]);
    for (auto *entry: descentants) {
      nodes.push_back(entry);
    }
  }
  return nodes;
}

std::vector<ParseTree *> Trees::descendants(ParseTree *t) {
  return getDescendants(t);
}

ParserRuleContext* Trees::getRootOfSubtreeEnclosingRegion(ParseTree *t, size_t startTokenIndex, size_t stopTokenIndex) {
  size_t n = t->children.size();
  for (size_t i = 0; i < n; i++) {
    ParserRuleContext *r = getRootOfSubtreeEnclosingRegion(t->children[i], startTokenIndex, stopTokenIndex);
    if (r != nullptr) {
      return r;
    }
  }

  if (is<ParserRuleContext *>(t)) {
    ParserRuleContext *r = dynamic_cast<ParserRuleContext *>(t);
    if (startTokenIndex >= r->getStart()->getTokenIndex() && // is range fully contained in t?
        (r->getStop() == nullptr || stopTokenIndex <= r->getStop()->getTokenIndex())) {
      // note: r.getStop()==null likely implies that we bailed out of parser and there's nothing to the right
      return r;
    }
  }
  return nullptr;
}

ParseTree * Trees::findNodeSuchThat(ParseTree *t, Ref<Predicate> const& pred) {
  if (pred->test(t)) {
    return t;
  }

  size_t n = t->children.size();
  for (size_t i = 0 ; i < n ; ++i) {
    ParseTree *u = findNodeSuchThat(t->children[i], pred);
    if (u != nullptr) {
      return u;
    }
  }

  return nullptr;
}

