/*
 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.h"
#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;
}
