/*
 Copyright 2019 Alain Dargelas

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
 */

/*
 * File:   SV3_1aTreeShapeHelper.cpp
 * Author: alain
 *
 * Created on June 25, 2017, 2:51 PM
 */

#include "SymbolTable.h"
#include "CommandLine/CommandLineParser.hpp"
#include "ErrorReporting/ErrorContainer.h"
#include "CompilationUnit.h"
#include "PreprocessFile.h"
#include "CompileSourceFile.h"
#include "Compiler.h"
#include "ParseFile.h"

#include <cstdlib>
#include <iostream>
#include "antlr4-runtime.h"
using namespace std;
using namespace antlr4;
using namespace SURELOG;

#include "parser/SV3_1aLexer.h"
#include "parser/SV3_1aParser.h"
#include "parser/SV3_1aParserBaseListener.h"
#include "SV3_1aTreeShapeHelper.h"
using namespace antlr4;
#include "Utils/ParseUtils.h"
#include "SV3_1aTreeShapeHelper.h"

SV3_1aTreeShapeHelper::SV3_1aTreeShapeHelper(ParseFile* pf,
                                             antlr4::CommonTokenStream* tokens,
                                             unsigned int lineOffset)
    : m_pf(pf),
      m_fileContent(NULL),
      m_currentElement(NULL),
      m_tokens(tokens),
      m_lineOffset(lineOffset),
      m_version(SystemVerilog) {
  if (pf->getCompileSourceFile())
    m_ppOutputFileLocation = pf->getCompileSourceFile()
                                 ->getCommandLineParser()
                                 ->usePPOutoutFileLocation();
}

SV3_1aTreeShapeHelper::SV3_1aTreeShapeHelper(ParseLibraryDef* pf,
                                             antlr4::CommonTokenStream* tokens)
    : m_pf(NULL),
      m_fileContent(NULL),
      m_currentElement(NULL),
      m_tokens(tokens),
      m_lineOffset(0),
      m_ppOutputFileLocation(false),
      m_version(SystemVerilog) {}

SV3_1aTreeShapeHelper::~SV3_1aTreeShapeHelper() {}

void SV3_1aTreeShapeHelper::logError(ErrorDefinition::ErrorType error,
                                     ParserRuleContext* ctx, std::string object,
                                     bool printColumn) {
  std::pair<int, int> lineCol = ParseUtils::getLineColumn(m_tokens, ctx);

  Location loc(
      m_pf->getFileId(lineCol.first /*+ m_lineOffset*/),
      m_pf->getLineNb(lineCol.first /*+ m_lineOffset*/),
      printColumn ? lineCol.second : 0,
      m_pf->getCompileSourceFile()->getSymbolTable()->registerSymbol(object));
  Error err(error, loc);
  m_pf->addError(err);
}

void SV3_1aTreeShapeHelper::logError(ErrorDefinition::ErrorType error,
                                     Location& loc, bool showDuplicates) {
  Error err(error, loc);
  m_pf->getCompileSourceFile()->getErrorContainer()->addError(err,
                                                              showDuplicates);
}

void SV3_1aTreeShapeHelper::logError(ErrorDefinition::ErrorType error,
                                     Location& loc, Location& extraLoc,
                                     bool showDuplicates) {
  std::vector<Location> extras;
  extras.push_back(extraLoc);
  Error err(error, loc, &extras);
  m_pf->getCompileSourceFile()->getErrorContainer()->addError(err,
                                                              showDuplicates);
}

NodeId SV3_1aTreeShapeHelper::generateDesignElemId() {
  return m_pf->getCompilationUnit()->generateUniqueDesignElemId();
}

NodeId SV3_1aTreeShapeHelper::generateNodeId() {
  return m_pf->getCompilationUnit()->generateUniqueNodeId();
}

SymbolId SV3_1aTreeShapeHelper::registerSymbol(std::string symbol) {
  return m_pf->getSymbolTable()->registerSymbol(symbol);
}

int SV3_1aTreeShapeHelper::registerObject(VObject& object) {
  m_fileContent->getVObjects().push_back(object);
  return LastObjIndex();
}

int SV3_1aTreeShapeHelper::LastObjIndex() {
  return m_fileContent->getVObjects().size() - 1;
}

int SV3_1aTreeShapeHelper::ObjectIndexFromContext(tree::ParseTree* ctx) {
  ContextToObjectMap::iterator itr = m_contextToObjectMap.find(ctx);
  if (itr == m_contextToObjectMap.end()) {
    return -1;
  } else {
    return (*itr).second;
  }
}

VObject& SV3_1aTreeShapeHelper::Object(NodeId index) {
  return m_fileContent->getVObjects()[index];
}

NodeId SV3_1aTreeShapeHelper::UniqueId(NodeId index) {
  // return m_fileContent->m_objects[index].m_uniqueId;
  return index;
}

SymbolId& SV3_1aTreeShapeHelper::Name(NodeId index) {
  return m_fileContent->getVObjects()[index].m_name;
}

NodeId& SV3_1aTreeShapeHelper::Child(NodeId index) {
  return m_fileContent->getVObjects()[index].m_child;
}

NodeId& SV3_1aTreeShapeHelper::Sibling(NodeId index) {
  return m_fileContent->getVObjects()[index].m_sibling;
}

NodeId& SV3_1aTreeShapeHelper::Definition(NodeId index) {
  return m_fileContent->getVObjects()[index].m_definition;
}

NodeId& SV3_1aTreeShapeHelper::Parent(NodeId index) {
  return m_fileContent->getVObjects()[index].m_parent;
}

unsigned short& SV3_1aTreeShapeHelper::Type(NodeId index) {
  return m_fileContent->getVObjects()[index].m_type;
}

unsigned int& SV3_1aTreeShapeHelper::Line(NodeId index) {
  return m_fileContent->getVObjects()[index].m_line;
}

void SV3_1aTreeShapeHelper::addNestedDesignElement(
    ParserRuleContext* ctx, std::string name, DesignElement::ElemType elemtype,
    VObjectType objtype) {
  SymbolId fileId;
  unsigned int line = getFileLine(ctx, fileId);

  DesignElement elem(registerSymbol(name), fileId, elemtype,
                     generateDesignElemId(), line, 0);
  elem.m_context = ctx;
  elem.m_timeInfo =
      m_pf->getCompilationUnit()->getTimeInfo(m_pf->getFileId(line), line);
  if (m_nestedElements.size()) {
    elem.m_timeInfo = m_nestedElements.top()->m_timeInfo;
    elem.m_parent = m_nestedElements.top()->m_uniqueId;
  }
  m_fileContent->getDesignElements().push_back(elem);
  m_currentElement = &m_fileContent->getDesignElements().back();
  m_nestedElements.push(m_currentElement);
}

void SV3_1aTreeShapeHelper::addDesignElement(ParserRuleContext* ctx,
                                             std::string name,
                                             DesignElement::ElemType elemtype,
                                             VObjectType objtype) {
  SymbolId fileId;
  unsigned int line = getFileLine(ctx, fileId);
  DesignElement elem(registerSymbol(name), fileId, elemtype,
                     generateDesignElemId(), line, 0);
  elem.m_context = ctx;
  elem.m_timeInfo =
      m_pf->getCompilationUnit()->getTimeInfo(m_pf->getFileId(line), line);
  m_fileContent->getDesignElements().push_back(elem);
  m_currentElement = &m_fileContent->getDesignElements().back();
}

unsigned int SV3_1aTreeShapeHelper::getFileLine(ParserRuleContext* ctx,
                                                SymbolId& fileId) {
  std::pair<int, int> lineCol = ParseUtils::getLineColumn(m_tokens, ctx);
  unsigned int line = 0;
  if (m_ppOutputFileLocation) {
    fileId = m_pf->getFileId(0);
    line = lineCol.first;
  } else {
    fileId = m_pf->getFileId(lineCol.first + m_lineOffset);
    line = m_pf->getLineNb(lineCol.first + m_lineOffset);
  }
  return line;
}

int SV3_1aTreeShapeHelper::addVObject(ParserRuleContext* ctx, std::string name,
                                      VObjectType objtype) {
  SymbolId fileId;
  unsigned int line = getFileLine(ctx, fileId);

  VObject object(registerSymbol(name), fileId, objtype, line, 0);
  m_fileContent->getVObjects().push_back(object);
  int objectIndex = m_fileContent->getVObjects().size() - 1;
  m_contextToObjectMap.insert(std::make_pair(ctx, objectIndex));
  addParentChildRelations(objectIndex, ctx);
  if (m_fileContent->getDesignElements().size()) {
    for (unsigned int i = 0; i <= m_fileContent->getDesignElements().size() - 1;
         i++) {
      DesignElement& elem =
          m_fileContent
              ->getDesignElements()[m_fileContent->getDesignElements().size() -
                                    1 - i];
      if (elem.m_context == ctx) {
        // Use the file and line number of the design object (package, module),
        // true file/line when splitting
        m_fileContent->getVObjects().back().m_fileId = elem.m_fileId;
        m_fileContent->getVObjects().back().m_line = elem.m_line;
        elem.m_node = objectIndex;
        break;
      }
    }
  }
  return objectIndex;
}

int SV3_1aTreeShapeHelper::addVObject(ParserRuleContext* ctx,
                                      VObjectType objtype) {
  SymbolId fileId;
  unsigned int line = getFileLine(ctx, fileId);

  VObject object(0, fileId, objtype, line, 0);
  m_fileContent->getVObjects().push_back(object);
  int objectIndex = m_fileContent->getVObjects().size() - 1;
  m_contextToObjectMap.insert(std::make_pair(ctx, objectIndex));
  addParentChildRelations(objectIndex, ctx);
  if (m_fileContent->getDesignElements().size()) {
    for (unsigned int i = 0; i <= m_fileContent->getDesignElements().size() - 1;
         i++) {
      DesignElement& elem =
          m_fileContent
              ->getDesignElements()[m_fileContent->getDesignElements().size() -
                                    1 - i];
      if (elem.m_context == ctx) {
        // Use the file and line number of the design object (package, module),
        // true file/line when splitting
        m_fileContent->getVObjects().back().m_fileId = elem.m_fileId;
        m_fileContent->getVObjects().back().m_line = elem.m_line;
        elem.m_node = objectIndex;
        break;
      }
    }
  }
  return objectIndex;
}

void SV3_1aTreeShapeHelper::addParentChildRelations(int indexParent,
                                                    ParserRuleContext* ctx) {
  int currentIndex = indexParent;
  for (tree::ParseTree* child : ctx->children) {
    int childIndex = ObjectIndexFromContext(child);
    if (childIndex != -1) {
      Parent(childIndex) = UniqueId(indexParent);
      if (currentIndex == indexParent) {
        Child(indexParent) = UniqueId(childIndex);
      } else {
        Sibling(currentIndex) = UniqueId(childIndex);
      }
      currentIndex = childIndex;
    }
  }
}

NodeId SV3_1aTreeShapeHelper::getObjectId(ParserRuleContext* ctx) {
  ContextToObjectMap::iterator itr = m_contextToObjectMap.find(ctx);
  if (itr == m_contextToObjectMap.end()) {
    return 0;
  } else {
    return (*itr).second;
  }
}

std::pair<double, TimeInfo::Unit> SV3_1aTreeShapeHelper::getTimeValue(
    SV3_1aParser::Time_literalContext* ctx) {
  double actual_value = 0;
  TimeInfo::Unit unit = TimeInfo::Second;
  if (ctx->Integral_number())
    actual_value = atoi(ctx->Integral_number()->getText().c_str());
  if (ctx->Real_number())
    actual_value = atoi(ctx->Real_number()->getText().c_str());
  unit = TimeInfo::unitFromString(ctx->time_unit()->getText());

  return std::make_pair(actual_value, unit);
}
