/*
 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:   ParseLibraryDef.cpp
 * Author: alain
 *
 * Created on January 27, 2018, 5:05 PM
 */
#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 "Library/ParseLibraryDef.h"
#include "Utils/FileUtils.h"
#include "antlr4-runtime.h"
#include "atn/ParserATNSimulator.h"
using namespace antlr4;
using namespace SURELOG;
#include "parser/SV3_1aLexer.h"
#include "parser/SV3_1aParser.h"
#include "Library/SVLibShapeListener.h"
#include "Library/AntlrLibParserErrorListener.h"

ParseLibraryDef::ParseLibraryDef(CommandLineParser* commandLineParser,
                                 ErrorContainer* errors,
                                 SymbolTable* symbolTable,
                                 LibrarySet* librarySet, ConfigSet* configSet)
    : m_fileId(0),
      m_commandLineParser(commandLineParser),
      m_errors(errors),
      m_symbolTable(symbolTable),
      m_librarySet(librarySet),
      m_configSet(configSet),
      m_fileContent(NULL) {}

ParseLibraryDef::ParseLibraryDef(const ParseLibraryDef& orig) {}

ParseLibraryDef::~ParseLibraryDef() {}

bool ParseLibraryDef::parseLibrariesDefinition() {
  // Get .map files from command line
  std::vector<SymbolId> libraryMapFiles =
      m_commandLineParser->getLibraryMapFiles();
  if (libraryMapFiles.empty()) {
    // or scan local dir
    libraryMapFiles = FileUtils::collectFiles("./", ".map", m_symbolTable);
  }

  // If "work" library is not yet declared from command line, create it
  std::string workN = "work";
  if (m_librarySet->getLibrary(workN) == NULL) {
    Library work(workN, m_symbolTable);
    m_librarySet->addLibrary(work);
  }

  // Config files are parsed using the library top rule
  std::vector<SymbolId> cfgFiles = m_commandLineParser->getConfigFiles();
  for (auto file : cfgFiles) {
    libraryMapFiles.push_back(file);
  }

  for (auto fileId : libraryMapFiles) {
    parseLibraryDefinition(fileId);
  }

  for (auto file : cfgFiles) {
    std::string fullPath =
        FileUtils::getFullPath(m_symbolTable->getSymbol(file));
    m_librarySet->getLibrary(m_symbolTable->registerSymbol(
        fullPath));  // Register configuration files in "work" library
  }

  unsigned int size = m_commandLineParser->getSourceFiles().size();
  for (unsigned int i = 0; i < size; i++) {
    SymbolId id = m_commandLineParser->getSourceFiles()[i];
    std::string fullPath = FileUtils::getFullPath(m_symbolTable->getSymbol(id));
    m_librarySet->getLibrary(m_symbolTable->registerSymbol(
        fullPath));  // Register files in "work" library
  }

  m_librarySet->checkErrors(m_symbolTable, m_errors);

  if (m_commandLineParser->getDebugLibraryDef()) {
    std::cout << m_librarySet->report(m_symbolTable) << std::endl;
  }
  return true;
}

bool ParseLibraryDef::parseLibraryDefinition(SymbolId fileId, Library* lib) {
  m_fileId = fileId;
  std::string fileName = m_symbolTable->getSymbol(fileId);
  std::string relativePath = FileUtils::getPathName(fileName);
  std::ifstream stream;
  stream.open(fileName);

  if (!stream.good()) {
    Location ppfile(fileId);
    Error err(ErrorDefinition::PA_CANNOT_OPEN_FILE, ppfile);
    m_errors->addError(err);
    return false;
  }

  Location ppfile(fileId);
  Error err(ErrorDefinition::PP_PROCESSING_SOURCE_FILE, ppfile);
  m_errors->addError(err);
  m_errors->printMessage(err, m_commandLineParser->muteStdout());

  AntlrLibParserErrorListener* errorListener =
      new AntlrLibParserErrorListener(this);
  antlr4::ANTLRInputStream* m_inputStream = new ANTLRInputStream(stream);
  SV3_1aLexer* m_lexer = new SV3_1aLexer(m_inputStream);
  m_lexer->removeErrorListeners();
  m_lexer->addErrorListener(errorListener);
  antlr4::CommonTokenStream* m_tokens = new CommonTokenStream(m_lexer);
  m_tokens->fill();
  SV3_1aParser* m_parser = new SV3_1aParser(m_tokens);
  m_parser->removeErrorListeners();
  m_parser->addErrorListener(errorListener);
  antlr4::tree::ParseTree* m_tree = m_parser->top_level_library_rule();

  SVLibShapeListener* m_listener =
      new SVLibShapeListener(this, m_tokens, relativePath);
  tree::ParseTreeWalker::DEFAULT.walk(m_listener, m_tree);
  m_fileContent = m_listener->getFileContent();

  if (m_fileContent->getLibrary() == NULL) {
    if (lib) {
      m_fileContent->setLibrary(lib);
    } else {
      std::string fullPath =
          FileUtils::getFullPath(m_symbolTable->getSymbol(m_fileId));
      m_fileContent->setLibrary(
          m_librarySet->getLibrary(m_symbolTable->registerSymbol(fullPath)));
    }
  }

  if (m_commandLineParser->getDebugAstModel()) {
    std::cout << m_fileContent->printObjects();
  }

  // delete m_tree;
  delete m_parser;
  delete m_tokens;
  delete m_lexer;
  delete m_inputStream;
  delete m_listener;
  return parseConfigDefinition();
}

bool ParseLibraryDef::parseConfigDefinition() {
  FileContent* fC = m_fileContent;
  if (!fC) return false;

  std::vector<VObjectType> types = {VObjectType::slConfig_declaration};
  std::vector<NodeId> configs = fC->sl_collect_all(0, types);
  for (auto config : configs) {
    NodeId ident = fC->Child(config);
    std::string name = fC->getLibrary()->getName() + "@" + fC->SymName(ident);
    m_symbolTable->registerSymbol(name);
    Config conf(name, fC, config);

    // Design clause
    std::vector<VObjectType> designStmt = {VObjectType::slDesign_statement};
    std::vector<NodeId> designs = fC->sl_collect_all(config, designStmt);
    if (designs.size() == 0) {
      // TODO: Error
    } else if (designs.size() > 1) {
      // TODO: Error
    } else {
      NodeId design = designs[0];
      NodeId libName = fC->Child(design);
      NodeId topName = fC->Sibling(libName);
      if (topName == 0) {
        conf.setDesignLib(fC->getLibrary()->getName());
        conf.setDesignTop(fC->SymName(libName));
      } else {
        conf.setDesignLib(fC->SymName(libName));
        conf.setDesignTop(fC->SymName(topName));
      }
    }

    // Default clause
    std::vector<VObjectType> defaultStmt = {VObjectType::slDefault_clause};
    std::vector<NodeId> defaults = fC->sl_collect_all(config, defaultStmt);
    if (defaults.size() > 0) {
      NodeId defaultClause = defaults[0];
      NodeId libList = fC->Sibling(defaultClause);
      if (fC->Type(libList) == VObjectType::slLiblist_clause) {
        NodeId lib = fC->Child(libList);
        while (lib) {
          conf.addDefaultLib(fC->SymName(lib));
          lib = fC->Sibling(lib);
        }
      }
    }

    // Instance and Cell clauses
    std::vector<VObjectType> instanceStmt = {VObjectType::slInst_clause,
                                             VObjectType::slCell_clause};
    std::vector<NodeId> instances = fC->sl_collect_all(config, instanceStmt);
    for (auto inst : instances) {
      VObjectType type = fC->Type(inst);
      NodeId instName = fC->Child(inst);
      if (type == slInst_clause) instName = fC->Child(instName);
      std::string instNameS;
      while (instName) {
        if (instNameS == "")
          instNameS = fC->SymName(instName);
        else
          instNameS += "." + fC->SymName(instName);
        instName = fC->Sibling(instName);
      }
      NodeId instClause = fC->Sibling(inst);
      if (fC->Type(instClause) == VObjectType::slLiblist_clause) {
        NodeId libList = fC->Child(instClause);
        std::vector<std::string> libs;
        while (libList) {
          libs.push_back(fC->SymName(libList));
          libList = fC->Sibling(libList);
        }

        UseClause usec(UseClause::UseLib, libs, fC, instClause);
        if (type == slInst_clause)
          conf.addInstanceUseClause(instNameS, usec);
        else
          conf.addCellUseClause(instNameS, usec);
      } else if (fC->Type(instClause) == VObjectType::slUse_clause) {
        NodeId use = fC->Child(instClause);
        std::string useName;
        VObjectType useType = fC->Type(use);
        if (useType == slParameter_value_assignment) {
          UseClause usec(UseClause::UseParam, fC, use);
          conf.addInstanceUseClause(instNameS, usec);
        } else {
          NodeId mem = use;
          while (use) {
            if (useName == "")
              useName = fC->SymName(use);
            else
              useName += "." + fC->SymName(use);
            use = fC->Sibling(use);
          }
          useName = StringUtils::replaceAll(useName, ".", "@");
          UseClause usec(UseClause::UseModule, useName, fC, mem);
          if (type == slInst_clause)
            conf.addInstanceUseClause(instNameS, usec);
          else
            conf.addCellUseClause(instNameS, usec);
        }
      } else if (fC->Type(instClause) == VObjectType::slUse_clause_config) {
        NodeId use = fC->Child(instClause);
        std::string useName;
        NodeId mem = use;
        while (use) {
          if (useName == "")
            useName = fC->SymName(use);
          else
            useName += "@" + fC->SymName(use);
          use = fC->Sibling(use);
        }
        UseClause usec(UseClause::UseConfig, useName, fC, mem);
        if (type == slInst_clause)
          conf.addInstanceUseClause(instNameS, usec);
        else
          conf.addCellUseClause(instNameS, usec);
      }
    }

    m_configSet->addConfig(conf);
  }

  return true;
}
