/*
 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 "SourceCompile/SymbolTable.h"
#include "CommandLine/CommandLineParser.h"
#include "ErrorReporting/ErrorContainer.h"
#include "SourceCompile/CompilationUnit.h"
#include "SourceCompile/PreprocessFile.h"
#include "SourceCompile/CompileSourceFile.h"
#include "SourceCompile/Compiler.h"
#include "SourceCompile/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 "SourceCompile/SV3_1aTreeShapeHelper.h"
using namespace antlr4;
#include "Utils/ParseUtils.h"
#include "SourceCompile/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);
}
