/*
 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:   CompileFileContent.cpp
 * Author: alain
 *
 * Created on March 28, 2018, 10:16 PM
 */
#include "SourceCompile/VObjectTypes.h"
#include "Design/VObject.h"
#include "Library/Library.h"
#include "Design/FileContent.h"
#include "SourceCompile/SymbolTable.h"
#include "ErrorReporting/Error.h"
#include "ErrorReporting/Location.h"
#include "ErrorReporting/Error.h"
#include "CommandLine/CommandLineParser.hpp"
#include "ErrorReporting/ErrorDefinition.h"
#include "ErrorReporting/ErrorContainer.h"
#include "SourceCompile/CompilationUnit.h"
#include "SourceCompile/PreprocessFile.h"
#include "SourceCompile/CompileSourceFile.h"
#include "SourceCompile/ParseFile.h"
#include "SourceCompile/Compiler.h"
#include "CompileDesign.h"
#include "CompileFileContent.h"
#include "CompileHelper.h"

using namespace SURELOG;

int FunctorCompileFileContent::operator()() const {
  CompileFileContent* instance = new CompileFileContent(
      m_compileDesign, m_fileContent, m_design, m_symbols, m_errors);
  instance->compile();
  delete instance;
  return true;
}

CompileFileContent::~CompileFileContent() {}

bool CompileFileContent::compile() { return collectObjects_(); }

bool CompileFileContent::collectObjects_() {
  std::vector<VObjectType> stopPoints = {
      VObjectType::slModule_declaration,  VObjectType::slInterface_declaration,
      VObjectType::slProgram_declaration, VObjectType::slClass_declaration,
      VObjectType::slPrimitive,           VObjectType::slPackage_declaration,
      VObjectType::slFunction_declaration};

  FileContent* fC = m_fileContent;
  if (fC->getSize() == 0) return true;
  VObject current = fC->Object(fC->getSize() - 2);
  NodeId id = current.m_child;
  if (!id) id = current.m_sibling;
  if (!id) return false;
  std::stack<NodeId> stack;
  stack.push(id);
  while (stack.size()) {
    id = stack.top();
    stack.pop();
    current = fC->Object(id);
    VObjectType type = fC->Type(id);
    switch (type) {
      case VObjectType::slPackage_import_item: {
        FileCNodeId fnid(fC, id);
        m_fileContent->addObject(type, fnid);
        break;
      }
      case VObjectType::slData_declaration: {
        NodeId subNode = fC->Child(id);
        VObjectType subType = fC->Type(subNode);
        switch (subType) {
          case VObjectType::slType_declaration: {
            /*
              n<> u<15> t<Data_type> p<17> c<8> s<16> l<13>
              n<fsm_t> u<16> t<StringConst> p<17> l<13>
              n<> u<17> t<Type_declaration> p<18> c<15> l<13>
              n<> u<18> t<Data_declaration> p<19> c<17> l<13>
            */
            m_helper.compileTypeDef(m_fileContent, m_fileContent, id);
            break;
          }
          default:
            break;
        }
        break;
      }
      default:
        break;
    }

    if (current.m_sibling) stack.push(current.m_sibling);
    if (current.m_child) {
      if (stopPoints.size()) {
        bool stop = false;
        for (auto t : stopPoints) {
          if (t == current.m_type) {
            stop = true;
            break;
          }
        }
        if (!stop)
          if (current.m_child) stack.push(current.m_child);
      } else {
        if (current.m_child) stack.push(current.m_child);
      }
    }
  }

  return true;
}
