/*
 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 "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 "CompilationUnit.h"
#include "PreprocessFile.h"
#include "CompileSourceFile.h"
#include "Compiler.h"
#include "ParseFile.h"
#include "../CommandLine/CommandLineParser.hpp"
#include "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;
}


