/*
 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);
}




