/*
 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:   SLAPI.cpp
 * Author: alain
 * 
 * Created on May 13, 2017, 4:42 PM
 */


#include <string>
#include <vector>

#include "../ErrorReporting/Waiver.h"
#include "../ErrorReporting/ErrorDefinition.h"
#include "../SourceCompile/SymbolTable.h"
#include "../ErrorReporting/ErrorContainer.h"
#include "../Utils/StringUtils.h"

#include "../CommandLine/CommandLineParser.hpp"
#include "../SourceCompile/CompilationUnit.h"
#include "../SourceCompile/PreprocessFile.h"
#include "../SourceCompile/CompileSourceFile.h"
#include "../SourceCompile/Compiler.h"
#include "../SourceCompile/ParseFile.h"
#include "../SourceCompile/PythonListen.h"
#include "../Design/FileContent.h"
#include "../Testbench/ClassDefinition.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_1aPythonListener.h"
#include "../Utils/ParseUtils.h"
#include "../Utils/FileUtils.h"
#include "PythonAPI.h"

#include "SLAPI.h"


void SURELOG::SLsetWaiver(const char* messageId, const char* fileName, unsigned int line, 
        const char* objectName) {
  if (fileName == 0 && line == 0 && objectName == 0) 
    {
       Waiver::setWaiver(messageId, "", 0, "");
    }
  else if (line == 0 && objectName == 0) 
    {
       Waiver::setWaiver(messageId, "", 0, fileName);
    }
  else if (objectName == 0) 
    {
       Waiver::setWaiver(messageId, fileName, line, "");
    }
  else 
    {
      Waiver::setWaiver(messageId, fileName, line, objectName);
    }
}

void SURELOG::SLregisterNewErrorType(const char* messageId, const char* text, const char* secondLine)
{
  //[WARNI:PP0103]
  std::string errorId = messageId;
  errorId = StringUtils::rtrim (errorId, ']');
  errorId = StringUtils::ltrim (errorId, '[');
  ErrorDefinition::ErrorType type = ErrorDefinition::getErrorType (messageId);
  ErrorDefinition::ErrorSeverity severity = ErrorDefinition::getErrorSeverity (errorId.substr (0,5));
  ErrorDefinition::ErrorCategory category = ErrorDefinition::getCategory (errorId.substr(6,2)); 
  ErrorDefinition::rec(type, severity, category, text, secondLine); 
}

void SURELOG::SLoverrideSeverity(const char* messageId, const char* severity) {
  ErrorDefinition::setSeverity (ErrorDefinition::getErrorType (messageId), ErrorDefinition::getErrorSeverity (severity));
}

void SURELOG::SLaddError(ErrorContainer* errors, const char* messageId, const char* fileName, unsigned int line, unsigned int col, const char* objectName) {
  if(errors == NULL)
    return;
  SymbolTable* symbolTable = errors->getSymbolTable ();
  SymbolId fileId = 0;
  if (fileName && (strcmp(fileName,"")))
      fileId = symbolTable->registerSymbol (fileName);
  SymbolId objectId = 0;
  if (objectName && (strcmp(objectName,"")))
      objectId = symbolTable->registerSymbol (objectName);
  Location loc(fileId, line, col, objectId);
  
  ErrorDefinition::ErrorType type = ErrorDefinition::getErrorType (messageId);
  Error err (type, loc);
  errors->addError (err, false, false);
  
}


void SURELOG::SLaddMLError(ErrorContainer* errors, const char* messageId, const char* fileName1, unsigned int line1, unsigned int col1, const char* objectName1, 
                                                             const char* fileName2, unsigned int line2, unsigned int col2, const char* objectName2) {
  if(errors == NULL)
    return;
  SymbolTable* symbolTable = errors->getSymbolTable ();
  SymbolId fileId1 = 0;
  if (fileName1 && (strcmp(fileName1,"")))
      fileId1 = symbolTable->registerSymbol (fileName1);
  SymbolId objectId1 = 0;
  if (objectName1 && (strcmp(objectName1,"")))
      objectId1 = symbolTable->registerSymbol (objectName1);
  Location loc1(fileId1, line1, col1, objectId1);
  
  SymbolId fileId2 = 0;
  if (fileName2 && (strcmp(fileName2,"")))
      fileId2 = symbolTable->registerSymbol (fileName2);
  SymbolId objectId2 = 0;
  if (objectName2 && (strcmp(objectName2,"")))
      objectId2 = symbolTable->registerSymbol (objectName2);
  Location loc2(fileId2, line2, col2, objectId2);
  
  ErrorDefinition::ErrorType type = ErrorDefinition::getErrorType (messageId);
  Error err (type, loc2, loc2);
  errors->addError (err, false, false);
}

void SURELOG::SLaddErrorContext(SV3_1aPythonListener* prog, ParserRuleContext* context, const char* messageId, const char* objectName, bool printColumn) {
  SV3_1aPythonListener* listener = (SV3_1aPythonListener*) prog; 
  ParserRuleContext* ctx = (ParserRuleContext*) context; 
  ErrorContainer* errors = listener->getPythonListen()->getCompileSourceFile()->getErrorContainer();
  std::pair<int, int> lineCol = ParseUtils::getLineColumn (listener->getTokenStream(), ctx);
  ErrorDefinition::ErrorType type = ErrorDefinition::getErrorType (messageId);

  Location loc (listener->getPythonListen()->getParseFile()->getFileId (lineCol.first), listener->getPythonListen()->getParseFile()->getLineNb (lineCol.first), printColumn ? lineCol.second : 0,
                listener->getPythonListen()->getCompileSourceFile()->getSymbolTable ()->registerSymbol(objectName));
  Error err (type, loc);
  errors->addError (err, false, false);  
}

void SURELOG::SLaddMLErrorContext(SV3_1aPythonListener* prog, ParserRuleContext* context1, ParserRuleContext* context2, const char* messageId, const char* objectName1, const char* objectName2, bool printColumn) {
  SV3_1aPythonListener* listener = (SV3_1aPythonListener*) prog; 
  ParserRuleContext* ctx1 = (ParserRuleContext*) context1; 
  ParserRuleContext* ctx2 = (ParserRuleContext*) context2; 
  ErrorContainer* errors = listener->getPythonListen()->getCompileSourceFile()->getErrorContainer();
  std::pair<int, int> lineCol1 = ParseUtils::getLineColumn (listener->getTokenStream(), ctx1);
  std::pair<int, int> lineCol2 = ParseUtils::getLineColumn (listener->getTokenStream(), ctx2);
  ErrorDefinition::ErrorType type = ErrorDefinition::getErrorType (messageId);

  Location loc1 (listener->getPythonListen()->getParseFile()->getFileId (lineCol1.first), listener->getPythonListen()->getParseFile()->getLineNb (lineCol1.first), printColumn ? lineCol1.second : 0,
                listener->getPythonListen()->getCompileSourceFile()->getSymbolTable ()->registerSymbol(objectName1));
  
  Location loc2 (listener->getPythonListen()->getParseFile()->getFileId (lineCol2.first), listener->getPythonListen()->getParseFile()->getLineNb (lineCol2.first), printColumn ? lineCol2.second : 0,
                listener->getPythonListen()->getCompileSourceFile()->getSymbolTable ()->registerSymbol(objectName2));
  Error err (type, loc1, loc2);
  errors->addError (err, false, false);  
}


std::string SURELOG::SLgetFile(SV3_1aPythonListener* prog, ParserRuleContext* context) {
  SV3_1aPythonListener* listener = (SV3_1aPythonListener*) prog; 
  std::string file = listener->getPythonListen()->getParseFile()->getFileName(0);
  return file;
}

int SURELOG::SLgetLine(SV3_1aPythonListener* prog, ParserRuleContext* context) {
  SV3_1aPythonListener* listener = (SV3_1aPythonListener*) prog; 
  ParserRuleContext* ctx = (ParserRuleContext*) context; 
  std::pair<int, int> lineCol = ParseUtils::getLineColumn (listener->getTokenStream(), ctx);
  return lineCol.first;
}

int SURELOG::SLgetColumn(SV3_1aPythonListener* prog, ParserRuleContext* context) {
  SV3_1aPythonListener* listener = (SV3_1aPythonListener*) prog; 
  ParserRuleContext* ctx = (ParserRuleContext*) context; 
  std::pair<int, int> lineCol = ParseUtils::getLineColumn (listener->getTokenStream(), ctx);
  return lineCol.second;
}


std::string SURELOG::SLgetText(SV3_1aPythonListener* /*prog*/, ParserRuleContext* context) {
  ParserRuleContext* ctx = (ParserRuleContext*) context; 
  std::vector<Token*> tokens = ParseUtils::getFlatTokenList (ctx);
  std::string text;
  for (auto token : tokens)
    {
      text += token->getText () + " ";
    }
  return text;
}

std::vector<std::string>
SURELOG::SLgetTokens (SV3_1aPythonListener* prog, ParserRuleContext* context)
{
  ParserRuleContext* ctx = (ParserRuleContext*) context;
  std::vector<Token*> tokens = ParseUtils::getFlatTokenList (ctx);
  std::vector<std::string> body_tokens;
  for (auto token : tokens)
    {
      body_tokens.push_back (token->getText ());
    }
  return body_tokens;
}


ParserRuleContext* SURELOG::SLgetParentContext(SV3_1aPythonListener* prog, ParserRuleContext* context) {
   ParserRuleContext* ctx = (ParserRuleContext*) context;
   return (ParserRuleContext*) ctx->parent;
}

std::vector<ParserRuleContext*>
SURELOG::SLgetChildrenContext (SV3_1aPythonListener* prog, ParserRuleContext* context)
{
  ParserRuleContext* ctx = (ParserRuleContext*) context;
  std::vector<ParserRuleContext*> children;
  
  for (unsigned int i = 0; i < ctx->children.size (); i++)
    {
      // Get the i-th child node of `parent`.
      tree::ParseTree* child = ctx->children[i];
      tree::TerminalNode* node = dynamic_cast<tree::TerminalNode*> (child);
      if (node)
        {
          // Terminal node 
        }
      else
        {
          // Rule
          children.push_back ((ParserRuleContext*) child);
        }
    }
  return children;
}


NodeId SURELOG::SLgetRootNode(FileContent* fC) {
  if (!fC)
    return 0;  
  return fC->getRootNode ();
}

std::string SURELOG::SLgetFile(FileContent* fC, NodeId id) {
  if (!fC)
    return "";  
  return fC->getSymbolTable ()->getSymbol (fC->getFileId (id));
}

unsigned int SURELOG::SLgetType(FileContent* fC, NodeId id) {
  if (!fC)
    return 0;  
  return fC->Type (id);
}

NodeId SURELOG::SLgetChild(FileContent* fC, NodeId index) {
  if (!fC)
    return 0;  
  return fC->Child (index);
}

NodeId SURELOG::SLgetSibling(FileContent* fC, NodeId index) {
  if (!fC)
    return 0;  
  return fC->Sibling (index);
}

NodeId SURELOG::SLgetParent(FileContent* fC, NodeId index) {
  if (!fC)
    return 0;  
  return fC->Parent (index);
}

unsigned int SURELOG::SLgetLine(FileContent* fC, NodeId index) {
  if (!fC)
    return 0;  
  return fC->Line (index);
}

std::string SURELOG::SLgetName(FileContent* fC, NodeId index) {
  if (!fC)
    return "";
  return fC->SymName (index);
}

NodeId SURELOG::SLgetChild(FileContent* fC, NodeId parent, unsigned int type) {
 if (!fC)
    return 0;  
  return fC->sl_get(parent, (VObjectType) type);
}
    
NodeId SURELOG::SLgetParent(FileContent* fC, NodeId parent, unsigned int type) {
  if (!fC)
    return 0;
  return fC->sl_parent(parent, (VObjectType) type);
}

std::vector<unsigned int> SURELOG::SLgetAll(FileContent* fC, NodeId parent, unsigned int type) {
  if (!fC)
    return {};
  return fC->sl_get_all(parent, (VObjectType) type);
}
    
std::vector<unsigned int> SURELOG::SLgetAll(FileContent* fC, NodeId parent, std::vector<unsigned int> types) {
  if (!fC)
    return {};
  std::vector<VObjectType> vtypes;
  for (auto type : types)
    vtypes.push_back ((VObjectType) type);
  return fC->sl_get_all(parent, vtypes);
}
    
NodeId SURELOG::SLcollect(FileContent* fC, NodeId parent, unsigned int type) {
  if (!fC)
    return {};
  return fC->sl_collect(parent, (VObjectType) type);
}
    
std::vector<unsigned int> SURELOG::SLcollectAll(FileContent* fC, NodeId parent, unsigned int type, bool first) {
  if (fC)
    return fC->sl_collect_all(parent, (VObjectType) type, first);
  else 
    return {};
}
    
std::vector<unsigned int> SURELOG::SLcollectAll(FileContent* fC, NodeId parent, std::vector<unsigned int> types, bool first) {
  if (!fC)
    return {};
  std::vector<VObjectType> vtypes;
  for (auto type : types)
    vtypes.push_back ((VObjectType) type);
  return fC->sl_collect_all(parent, vtypes, first);
}
    
std::vector<unsigned int> SURELOG::SLcollectAll(FileContent* fC, NodeId parent, std::vector<unsigned int> types, std::vector<unsigned int> stopPoints, bool first) {
 if (!fC)
    return {};  
  std::vector<VObjectType> vtypes;
  for (auto type : types)
    vtypes.push_back ((VObjectType) type);
  std::vector<VObjectType> vstops;
  for (auto type : stopPoints)
    vstops.push_back ((VObjectType) type);
   return fC->sl_collect_all(parent, vtypes, vstops, first);
}

unsigned int SURELOG::SLgetnModuleDefinition(Design* design) {
  if (!design)
    return 0;
  return design->getModuleDefinitions ().size();
}

unsigned int SURELOG::SLgetnProgramDefinition(Design* design) {
   if (!design)
    return 0;
  return design->getProgramDefinitions ().size();
}

unsigned int SURELOG::SLgetnPackageDefinition(Design* design) {
   if (!design)
    return 0;
  return design->getPackageDefinitions ().size();
}

unsigned int SURELOG::SLgetnClassDefinition(Design* design) {
   if (!design)
    return 0;
  return design->getUniqueClassDefinitions ().size();
}

unsigned int SURELOG::SLgetnTopModuleInstance(Design* design) {
  if (!design)
    return 0;
  return design->getTopLevelModuleInstances ().size();
}

ModuleDefinition* SURELOG::SLgetModuleDefinition(Design* design, unsigned int index) {
   if (!design)
    return 0;
  ModuleNameModuleDefinitionMap::iterator itr = design->getModuleDefinitions().begin();
  for (unsigned int i = 0; i < index; i++)
    itr++;
  return (*itr).second;
}

Program* SURELOG::SLgetProgramDefinition(Design* design, unsigned int index) {
   if (!design)
    return 0;
  ProgramNameProgramDefinitionMap::iterator itr = design->getProgramDefinitions().begin();
  for (unsigned int i = 0; i < index; i++)
    itr++;
  return (*itr).second;
}

Package* SURELOG::SLgetPackageDefinition(Design* design, unsigned int index) {
   if (!design)
    return 0;
  PackageNamePackageDefinitionMultiMap::iterator itr = design->getPackageDefinitions().begin();
  for (unsigned int i = 0; i < index; i++)
    itr++;
  return (*itr).second;
}

ClassDefinition* SURELOG::SLgetClassDefinition(Design* design, unsigned int index) {
   if (!design)
    return 0;
  ClassNameClassDefinitionMap::iterator itr = design->getUniqueClassDefinitions().begin();
  for (unsigned int i = 0; i < index; i++)
    itr++;
  return (*itr).second;
}

ModuleInstance* SURELOG::SLgetTopModuleInstance(Design* design, unsigned int index) {
  if (!design)
    return 0;
  return design->getTopLevelModuleInstances()[index];
}

std::string SURELOG::SLgetModuleName(ModuleDefinition* module) {
   if (!module)
    return "";
  return module->getName();
}

std::string SURELOG::SLgetModuleFile(ModuleDefinition* module) {
    if (!module)
    return "";
  if (module->getFileContents().size())
    return module->getFileContents()[0]->getFileName(module->getNodeIds ()[0]);
  else
    return "";
}

unsigned int SURELOG::SLgetModuleLine(ModuleDefinition* module) {
    if (!module)
    return 0;
  if (module->getFileContents().size())
   return module->getFileContents()[0]->Line (module->getNodeIds ()[0]);
  else 
    return 0;
}

VObjectType SURELOG::SLgetModuleType(ModuleDefinition* module) {
    if (!module)
    return VObjectType::slNoType;
  return module->getType();
}

FileContent* SURELOG::SLgetModuleFileContent(ModuleDefinition* module) {
    if (!module)
    return NULL;
   if (module->getFileContents().size())
    return module->getFileContents()[0];
  else
    return NULL;
}

NodeId SURELOG::SLgetModuleRootNode(ModuleDefinition* module)
{
  if (!module)
    return 0;
  if (module->getFileContents().size())
   return module->getNodeIds ()[0];
  else 
    return 0;
}

std::string SURELOG::SLgetClassName(ClassDefinition* module) {
   if (!module)
    return "";
  return module->getName();
}

std::string SURELOG::SLgetClassFile(ClassDefinition* module) {
   if (!module)
    return "";
  if (module->getFileContents().size() && module->getFileContents()[0])
    return module->getFileContents()[0]->getFileName(module->getNodeIds ()[0]);
  else
    return "";
}

unsigned int SURELOG::SLgetClassLine(ClassDefinition* module) {
   if (!module)
    return 0;
  if (module->getFileContents().size() && module->getFileContents()[0])
   return module->getFileContents()[0]->Line (module->getNodeIds ()[0]);
  else 
    return 0;
}

VObjectType SURELOG::SLgetClassType(ClassDefinition* module) {
   if (!module)
    return VObjectType::slNoType;
  return module->getType();
}

FileContent* SURELOG::SLgetClassFileContent(ClassDefinition* module) {
   if (!module)
    return 0;
   if (module->getFileContents().size() && module->getFileContents()[0])
    return module->getFileContents()[0];
  else
    return NULL;
}

NodeId SURELOG::SLgetClassRootNode(ClassDefinition* module) {
   if (!module)
    return 0;
  if (module->getFileContents().size() && module->getFileContents()[0])
   return module->getNodeIds ()[0];
  else 
    return 0;
}

std::string SURELOG::SLgetPackageName(Package* module) {
   if (!module)
    return "";
  return module->getName();
}

std::string SURELOG::SLgetPackageFile(Package* module) {
   if (!module)
    return "";
  if (module->getFileContents().size())
    return module->getFileContents()[0]->getFileName(module->getNodeIds ()[0]);
  else
    return "";
}

unsigned int SURELOG::SLgetPackageLine(Package* module) {
   if (!module)
    return 0;
  if (module->getFileContents().size())
   return module->getFileContents()[0]->Line (module->getNodeIds ()[0]);
  else 
    return 0;
}

VObjectType SURELOG::SLgetPackageType(Package* module) {
   if (!module)
    return VObjectType::slNoType;
  return module->getType();
}

FileContent* SURELOG::SLgetPackageFileContent(Package* module) {
   if (!module)
    return 0;
   if (module->getFileContents().size())
    return module->getFileContents()[0];
  else
    return NULL;
}

NodeId SURELOG::SLgetPackageRootNode(Package* module) {
   if (!module)
    return 0;
  if (module->getFileContents().size())
   return module->getNodeIds ()[0];
  else 
    return 0;
}

std::string
SURELOG::SLgetProgramName (Program* module)
{
  if (!module)
    return "";
  return module->getName ();
}

std::string
SURELOG::SLgetProgramFile (Program* module)
{
  if (!module)
    return "";
  if (module->getFileContents ().size ())
    return module->getFileContents ()[0]->getFileName (module->getNodeIds ()[0]);
  else
    return "";
}

unsigned int
SURELOG::SLgetProgramLine (Program* module)
{
  if (!module)
    return 0;
  if (module->getFileContents ().size ())
    return module->getFileContents ()[0]->Line (module->getNodeIds ()[0]);
  else
    return 0;
}

VObjectType
SURELOG::SLgetProgramType (Program* module)
{
  if (!module)
    return VObjectType::slNoType;
  return module->getType ();
}

FileContent*
SURELOG::SLgetProgramFileContent (Program* module)
{
  if (!module)
    return 0;
  if (module->getFileContents ().size ())
    return module->getFileContents ()[0];
  else
    return NULL;
}

NodeId
SURELOG::SLgetProgramRootNode (Program* module)
{
  if (!module)
    return 0;
  if (module->getFileContents ().size ())
    return module->getNodeIds ()[0];
  else
    return 0;
}

VObjectType
SURELOG::SLgetInstanceType (ModuleInstance* instance)
{
  if (!instance)
    return VObjectType::slNoType;
  return instance->getType ();
}

VObjectType
SURELOG::SLgetInstanceModuleType (ModuleInstance* instance)
{
  if (!instance)
    return VObjectType::slNoType;
  return instance->getModuleType ();
}

std::string
SURELOG::SLgetInstanceName (ModuleInstance* instance)
{
  if (!instance)
    return "";
  return instance->getInstanceName ();
}

std::string
SURELOG::SLgetInstanceFullPathName (ModuleInstance* instance)
{
  if (!instance)
    return "";
  return instance->getFullPathName ();
}

std::string
SURELOG::SLgetInstanceModuleName (ModuleInstance* instance)
{
  if (!instance)
    return "";
  return instance->getModuleName ();
}

DesignComponent*
SURELOG::SLgetInstanceDefinition (ModuleInstance* instance)
{
  if (!instance)
    return NULL;
  return instance->getDefinition ();
}

std::string
SURELOG::SLgetInstanceFileName (ModuleInstance* instance)
{
  if (!instance)
    return "";
  return instance->getFileContent ()->getFileName (instance->getNodeId ());
}

FileContent*
SURELOG::SLgetInstanceFileContent (ModuleInstance* instance)
{
  if (!instance)
    return NULL;
  return instance->getFileContent ();
}

NodeId
SURELOG::SLgetInstanceNodeId (ModuleInstance* instance)
{
  if (!instance)
    return 0;
  return instance->getNodeId ();
}

unsigned int
SURELOG::SLgetInstanceLine (ModuleInstance* instance)
{
  if (!instance)
    return 0;
  return instance->getLineNb ();
}

unsigned int
SURELOG::SLgetnInstanceChildren (ModuleInstance* instance)
{
  if (!instance)
    return 0;
  return instance->getNbChildren ();
}

ModuleInstance*
SURELOG::SLgetInstanceChildren (ModuleInstance* instance, unsigned int i)
{
  if (!instance)
    return NULL;
  return instance->getChildren (i);
}

ModuleInstance*
SURELOG::SLgetInstanceParent (ModuleInstance* instance)
{
  if (!instance)
    return NULL;
  return instance->getParent ();
} 


