/*
 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:   CompileSourceFile.cpp
 * Author: alain
 *
 * Created on February 20, 2017, 9:54 PM
 */
#include "../CommandLine/CommandLineParser.hpp"
#include "../ErrorReporting/ErrorContainer.h"
#include "SymbolTable.h"
#include "CompilationUnit.h"
#include "PreprocessFile.h"
#include "CompilationUnit.h"

#include "antlr4-runtime.h"
using namespace antlr4;
#include "../parser/SV3_1aLexer.h"
#include "../parser/SV3_1aParser.h"

#include "AntlrParserHandler.h"

#include "CompileSourceFile.h"
#include "Compiler.h"
#include "../Utils/StringUtils.h"
#include "../Utils/FileUtils.h"
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
using namespace std;
#include "PreprocessFile.h"
#include "ParseFile.h"
#include "../API/PythonAPI.h"
#include "PythonListen.h"
#include "../Package/Precompiled.h"

using namespace SURELOG;

CompileSourceFile::CompileSourceFile(SymbolId fileId, CommandLineParser* clp,
                                     ErrorContainer* errors, Compiler* compiler,
                                     SymbolTable* symbols,
                                     CompilationUnit* compilationUnit,
                                     Library* library)
    : m_fileId(fileId),
      m_commandLineParser(clp),
      m_errors(errors),
      m_compiler(compiler),
      m_pp(NULL),
      m_symbolTable(symbols),
      m_parser(NULL),
      m_compilationUnit(compilationUnit),
      m_action(Preprocess),
      m_ppResultFileId(0),
      m_interpState(NULL),
      m_pythonListener(NULL),
      m_fileAnalyzer(NULL),
      m_library(library) {}

CompileSourceFile::CompileSourceFile(CompileSourceFile* parent,
                                     SymbolId ppResultFileId,
                                     unsigned int lineOffset)
    : m_fileId(parent->m_fileId),
      m_commandLineParser(parent->m_commandLineParser),
      m_errors(parent->m_errors),
      m_compiler(parent->m_compiler),
      m_pp(parent->m_pp),
      m_symbolTable(NULL),
      m_parser(NULL),
      m_compilationUnit(parent->m_compilationUnit),
      m_action(Parse),
      m_ppResultFileId(ppResultFileId),
      m_interpState(parent->m_interpState),
      m_pythonListener(NULL),
      m_fileAnalyzer(parent->m_fileAnalyzer),
      m_library(parent->m_library) {
  m_parser =
      new ParseFile(this, parent->m_parser, m_ppResultFileId, lineOffset);
}

bool CompileSourceFile::compile(Action action) {
  m_action = action;
  if (m_commandLineParser->verbose()) {
    Location loc(m_fileId);
    ErrorDefinition::ErrorType type =
        ErrorDefinition::PP_PROCESSING_SOURCE_FILE;
    switch (m_action) {
      case Preprocess:
      case PostPreprocess:
        type = ErrorDefinition::PP_PROCESSING_SOURCE_FILE;
        break;
      case Parse:
        type = ErrorDefinition::PA_PROCESSING_SOURCE_FILE;
        break;
      case PythonAPI:
        type = ErrorDefinition::PY_PROCESSING_SOURCE_FILE;
        break;
    }
    if (action != PostPreprocess) {
      Error err(type, loc);
      m_errors->printMessage(m_errors->addError(err, true));
    }
  }

  switch (m_action) {
    case Preprocess:
      return preprocess_();
    case PostPreprocess:
      return postPreprocess_();
    case Parse:
      return parse_();
    case PythonAPI:
      return pythonAPI_();
  }
  return true;
}

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

CompileSourceFile::~CompileSourceFile() {
  std::vector<PreprocessFile*>::iterator itr;
  for (itr = m_ppIncludeVec.begin(); itr != m_ppIncludeVec.end(); itr++) {
    delete *itr;
  }

  if (m_parser) delete m_parser;

  if (m_pythonListener) delete m_pythonListener;

  std::map<SymbolId, PreprocessFile::AntlrParserHandler*>::iterator itr2;
  for (itr2 = m_antlrPpMap.begin(); itr2 != m_antlrPpMap.end(); itr2++) {
    delete (*itr2).second;
  }
}

unsigned int CompileSourceFile::getJobSize(Action action) {
  switch (action) {
    case Preprocess:
    case PostPreprocess: {
      std::string fileName = getSymbolTable()->getSymbol(m_fileId);
      return FileUtils::fileSize(fileName);
    }
    case Parse: {
      std::string fileName = getSymbolTable()->getSymbol(m_ppResultFileId);
      return FileUtils::fileSize(fileName);
    }
    case PythonAPI: {
      std::string fileName = getSymbolTable()->getSymbol(m_ppResultFileId);
      return FileUtils::fileSize(fileName);
    }
  };
  return 0;
}

bool CompileSourceFile::pythonAPI_() {
  if (getCommandLineParser()->pythonListener()) {
    m_pythonListener = new PythonListen(m_parser, this);
    if (!m_pythonListener->listen()) {
      return false;
    }
    bool fatalErrors = m_errors->hasFatalErrors();
    if (fatalErrors) {
      return false;
    }
  }
  if (getCommandLineParser()->pythonEvalScriptPerFile()) {
    PythonAPI::evalScriptPerFile(
        getCommandLineParser()->getSymbolTable()->getSymbol(
            getCommandLineParser()->pythonEvalScriptPerFileId()),
        m_errors, m_parser->getFileContent(), m_interpState);
  }
  return true;
}

bool CompileSourceFile::initParser() {
  if (m_parser == NULL)
    m_parser = new ParseFile(m_fileId, this, m_compilationUnit, m_library,
                             m_ppResultFileId,
                             getCommandLineParser()->pythonListener());
  return true;
}

bool CompileSourceFile::parse_() {
  initParser();
  if (!m_parser->parse()) {
    return false;
  }
  bool fatalErrors = m_errors->hasFatalErrors();
  if (fatalErrors) {
    return false;
  }
  return true;
}

bool CompileSourceFile::preprocess_() {
  Precompiled* prec = Precompiled::getSingleton();
  std::string root = getSymbolTable()->getSymbol(m_fileId);
  root = StringUtils::getRootFileName(root);

  PreprocessFile::SpecialInstructions instructions(
      PreprocessFile::SpecialInstructions::DontMute,
      PreprocessFile::SpecialInstructions::DontMark,
      m_commandLineParser->filterFileLine()
          ? PreprocessFile::SpecialInstructions::Filter
          : PreprocessFile::SpecialInstructions::DontFilter,
      PreprocessFile::SpecialInstructions::CheckLoop,
      PreprocessFile::SpecialInstructions::ComplainUndefinedMacro);
  m_pp = new PreprocessFile(m_fileId, this, instructions, m_compilationUnit,
                            m_library);
  registerPP(m_pp);

  if (!m_pp->preprocess()) {
    return false;
  }
  bool fatalErrors = m_errors->hasFatalErrors();
  if (fatalErrors) {
    return false;
  }

  if (m_commandLineParser->getDebugIncludeFileInfo())
    std::cout << m_pp->reportIncludeInfo();

  if ((!m_commandLineParser->createCache()) && prec->isFilePrecompiled(root))
    return true;

  m_pp->saveCache();
  return true;
}

bool CompileSourceFile::postPreprocess_() {
  std::string m_pp_result = m_pp->getPreProcessedFileContent();
  if (m_commandLineParser->writePpOutput() ||
      (m_commandLineParser->writePpOutputFileId() != 0)) {
    SymbolTable* symbolTable = getCompiler()->getSymbolTable();
    const std::string& directory =
        symbolTable->getSymbol(m_commandLineParser->getFullCompileDir());
    std::string fileName = symbolTable->getSymbol(m_fileId);
    std::string fullPath = FileUtils::getFullPath(fileName);
    fileName = StringUtils::eliminateRelativePath(fileName);
    const std::string& writePpOutputFileName =
        symbolTable->getSymbol(m_commandLineParser->writePpOutputFileId());
    std::string libName = m_library->getName() + "/";
    string ppFileName = m_commandLineParser->writePpOutput()
                            ? directory + libName + fileName
                            : writePpOutputFileName;
    std::string dirPpFile = ppFileName;
    StringUtils::rtrim(dirPpFile, '/');
    SymbolId ppOutId = symbolTable->registerSymbol(ppFileName);
    m_ppResultFileId = m_symbolTable->registerSymbol(ppFileName);
    SymbolId ppDirId = symbolTable->registerSymbol(dirPpFile);

    if (FileUtils::mkDir(dirPpFile.c_str()) != 0) {
      Location loc(ppDirId);
      Error err(ErrorDefinition::PP_CANNOT_CREATE_DIRECTORY, loc);
      m_errors->addError(err);
      return false;
    }
    if ((!m_pp->usingCachedVersion()) || (!FileUtils::fileExists(ppFileName))) {
      ofstream ofs;
      ofs.open(ppFileName);
      if (ofs.good()) {
        ofs << m_pp_result;
        ofs.close();
      } else {
        Location loc(ppOutId);
        Error err(ErrorDefinition::PP_OPEN_FILE_FOR_WRITE, loc);
        m_errors->addError(err);
        return false;
      }
    }
  }
  return true;
}

void CompileSourceFile::registerAntlrPpHandlerForId(
    SymbolId id, PreprocessFile::AntlrParserHandler* pp) {
  std::map<SymbolId, PreprocessFile::AntlrParserHandler*>::iterator itr =
      m_antlrPpMap.find(id);
  if (itr != m_antlrPpMap.end()) {
    delete (*itr).second;
    m_antlrPpMap.erase(itr);
    m_antlrPpMap.insert(std::make_pair(id, pp));
    return;
  }
  m_antlrPpMap.insert(std::make_pair(id, pp));
}

PreprocessFile::AntlrParserHandler* CompileSourceFile::getAntlrPpHandlerForId(
    SymbolId id) {
  std::map<SymbolId, PreprocessFile::AntlrParserHandler*>::iterator itr =
      m_antlrPpMap.find(id);
  if (itr != m_antlrPpMap.end()) {
    PreprocessFile::AntlrParserHandler* ptr = (*itr).second;
    return ptr;
  }
  return NULL;
}

void CompileSourceFile::setSymbolTable(SymbolTable* symbols) {
  m_symbolTable = symbols;
}

void CompileSourceFile::setPythonInterp(PyThreadState* interpState) {
  m_interpState = interpState;
  m_errors->setPythonInterp(interpState);
}

void CompileSourceFile::shutdownPythonInterp() {
  m_errors->setPythonInterp(NULL);
  PythonAPI::shutdown(m_interpState);
  m_interpState = NULL;
}
