/*
 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:   CheckCompile.cpp
 * Author: alain
 *
 * Created on June 10, 2017, 10:15 PM
 */
#include <iostream>
#include <set>
#include "SourceCompile/SymbolTable.h"
#include "Design/TimeInfo.h"
#include "Design/DesignElement.h"
#include "Design/FileContent.h"
#include "ErrorReporting/Location.h"
#include "ErrorReporting/Error.h"
#include "ErrorReporting/ErrorDefinition.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 "CommandLine/CommandLineParser.hpp"
#include "SourceCompile/CheckCompile.h"

using namespace SURELOG;

CheckCompile::~CheckCompile() {}

bool CheckCompile::check() {
  if (!mergeSymbolTables_()) return false;
  if (!checkTimescale_()) return false;
  return true;
}

bool CheckCompile::mergeSymbolTables_() {
  Design::FileIdDesignContentMap& all_files =
      m_compiler->getDesign()->getAllFileContents();
  for (auto fitr = all_files.begin(); fitr != all_files.end(); fitr++) {
    auto fileContent = (*fitr).second;
    m_compiler->getSymbolTable()->registerSymbol(fileContent->getFileName());
    for (NodeId id : fileContent->getNodeIds()) {
      fileContent->getFileId(id) = m_compiler->getSymbolTable()->registerSymbol(
          fileContent->getSymbolTable()->getSymbol(fileContent->getFileId(id)));
    }
    for (DesignElement& elem : fileContent->getDesignElements()) {
      elem.m_name = m_compiler->getSymbolTable()->registerSymbol(
          fileContent->getSymbolTable()->getSymbol(elem.m_name));
      elem.m_fileId = m_compiler->getSymbolTable()->registerSymbol(
          fileContent->getSymbolTable()->getSymbol(
              fileContent->getFileId(elem.m_node)));
    }
  }
  return true;
}

bool CheckCompile::checkTimescale_() {
  std::string globaltimescale =
      m_compiler->getCommandLineParser()->getTimeScale();
  if (globaltimescale != "") {
    Location loc(0, 0, 0,
                 m_compiler->getSymbolTable()->registerSymbol(globaltimescale));
    Error err(ErrorDefinition::CMD_USING_GLOBAL_TIMESCALE, loc);
    m_compiler->getErrorContainer()->addError(err);
    return true;
  }

  bool timeUnitUsed = false;
  bool timeScaleUsed = false;
  std::vector<Location> noTimeUnitLocs;
  Design::FileIdDesignContentMap& all_files =
      m_compiler->getDesign()->getAllFileContents();
  std::unordered_set<SymbolId> reportedMissingTimescale;
  std::unordered_set<SymbolId> reportedMissingTimeunit;
  for (auto fitr = all_files.begin(); fitr != all_files.end(); fitr++) {
    auto fileContent = (*fitr).second;
    for (auto elem : fileContent->getDesignElements()) {
      if (elem.m_type == DesignElement::Module ||
          elem.m_type == DesignElement::Interface ||
          elem.m_type == DesignElement::Package ||
          elem.m_type == DesignElement::Primitive ||
          elem.m_type == DesignElement::Program) {
        if (elem.m_timeInfo.m_type == TimeInfo::TimeUnitTimePrecision) {
          timeUnitUsed = true;
        } else if (elem.m_timeInfo.m_type == TimeInfo::Timescale) {
          timeScaleUsed = true;
          Location loc(m_compiler->getSymbolTable()->registerSymbol(
                           fileContent->getSymbolTable()->getSymbol(
                               fileContent->getFileId(elem.m_node))),
                       elem.m_line, 0, elem.m_name);
          noTimeUnitLocs.push_back(loc);
        } else {
          Location loc(m_compiler->getSymbolTable()->registerSymbol(
                           fileContent->getSymbolTable()->getSymbol(
                               fileContent->getFileId(elem.m_node))),
                       elem.m_line, 0, elem.m_name);
          noTimeUnitLocs.push_back(loc);
          if (reportedMissingTimescale.find(elem.m_name) ==
              reportedMissingTimescale.end()) {
            reportedMissingTimescale.insert(elem.m_name);
            Error err(ErrorDefinition::PA_NOTIMESCALE_INFO, loc);
            m_compiler->getErrorContainer()->addError(err);
          }
        }
      }
    }
  }
  if (timeUnitUsed && timeScaleUsed) {
    for (auto loc : noTimeUnitLocs) {
      if (reportedMissingTimeunit.find(loc.m_object) ==
          reportedMissingTimeunit.end()) {
        reportedMissingTimeunit.insert(loc.m_object);
        Error err(ErrorDefinition::PA_MISSING_TIMEUNIT, loc);
        m_compiler->getErrorContainer()->addError(err);
      }
    }
  }

  return true;
}
