/*
 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:   FileContent.cpp
 * Author: alain
 *
 * Created on June 8, 2017, 8:22 PM
 */

#include "SourceCompile/SymbolTable.h"
#include "TimeInfo.h"
#include "DesignElement.h"
#include "Library/Library.h"
#include "ErrorReporting/ErrorContainer.h"
#include "FileContent.h"
#include <queue>
#include <iostream>
#include <stack>

using namespace SURELOG;

FileContent::~FileContent() {}

NodeId FileContent::getRootNode() {
  if (m_objects.size() == 0) {
    return 0;
  }
  return m_objects[0].m_sibling;
}

SymbolId& FileContent::getFileId(NodeId id) { return m_objects[id].m_fileId; }

std::string FileContent::getFileName(NodeId id) {
  SymbolId fileId = m_objects[id].m_fileId;
  return m_symbolTable->getSymbol(fileId);
}

std::string FileContent::printObjects() {
  std::string text;
  NodeId index = 0;

  if (m_library) text += "LIB:  " + m_library->getName() + "\n";
  text += "FILE: " + m_symbolTable->getSymbol(m_fileId) + "\n";

  for (auto object : m_objects) {
    text += object.print(m_symbolTable, index, GetDefinitionFile(index));
    text += "\n";
    index++;
  }
  return text;
}

unsigned int FileContent::getSize() { return m_objects.size(); }

std::string FileContent::printSubTree(NodeId uniqueId) {
  std::string text;
  for (auto s : collectSubTree(uniqueId)) {
    text += s + "\n";
  }
  return text;
}

void FileContent::insertObjectLookup(std::string name, NodeId id,
                                     ErrorContainer* errors) {
  NameIdMap::iterator itr = m_objectLookup.find(name);
  if (itr == m_objectLookup.end()) {
    m_objectLookup.insert(std::make_pair(name, id));
  } else {
    Location loc(errors->getSymbolTable()->registerSymbol(getFileName(id)),
                 Line(id), 0, errors->getSymbolTable()->registerSymbol(name));
    Location loc2(
        errors->getSymbolTable()->registerSymbol(getFileName((*itr).second)),
        Line((*itr).second), 0);
    Error err(ErrorDefinition::COMP_MULTIPLY_DEFINED_DESIGN_UNIT, loc, loc2);
    errors->addError(err);
  }
}

ModuleDefinition* FileContent::getModuleDefinition(
    const std::string& moduleName) {
  ModuleNameModuleDefinitionMap::iterator itr =
      m_moduleDefinitions.find(moduleName);
  if (itr != m_moduleDefinitions.end()) {
    return (*itr).second;
  }
  return NULL;
}

DesignComponent* FileContent::getComponentDefinition(
    const std::string& componentName) {
  DesignComponent* comp = (DesignComponent*)getModuleDefinition(componentName);
  if (comp) return comp;
  comp = (DesignComponent*)getProgram(componentName);
  if (comp) return comp;
  comp = (DesignComponent*)getClassDefinition(componentName);
  if (comp) return comp;
  return NULL;
}

Package* FileContent::getPackage(const std::string& name) {
  PackageNamePackageDefinitionMultiMap::iterator itr =
      m_packageDefinitions.find(name);
  if (itr == m_packageDefinitions.end()) {
    return NULL;
  } else {
    return (*itr).second;
  }
}

Program* FileContent::getProgram(const std::string& name) {
  ProgramNameProgramDefinitionMap::iterator itr =
      m_programDefinitions.find(name);
  if (itr == m_programDefinitions.end()) {
    return NULL;
  } else {
    return (*itr).second;
  }
}

ClassDefinition* FileContent::getClassDefinition(const std::string& name) {
  ClassNameClassDefinitionMultiMap::iterator itr =
      m_classDefinitions.find(name);
  if (itr == m_classDefinitions.end()) {
    return NULL;
  } else {
    return (*itr).second;
  }
}

std::vector<std::string> FileContent::collectSubTree(NodeId index) {
  std::vector<std::string> text;

  text.push_back(
      m_objects[index].print(m_symbolTable, index, GetDefinitionFile(index)));

  if (m_objects[index].m_child) {
    for (auto s : collectSubTree(m_objects[index].m_child)) {
      text.push_back("    " + s);
    }
  }

  if (m_objects[index].m_sibling) {
    for (auto s : collectSubTree(m_objects[index].m_sibling)) {
      text.push_back(s);
    }
  }

  return text;
}

void FileContent::SetDefinitionFile(NodeId index, SymbolId def) {
  m_definitionFiles.insert(std::make_pair(index, def));
}

SymbolId FileContent::GetDefinitionFile(NodeId index) {
  auto itr = m_definitionFiles.find(index);
  if (itr != m_definitionFiles.end()) return (*itr).second;
  return 0;
}

VObject& FileContent::Object(NodeId index) { return m_objects[index]; }

NodeId FileContent::UniqueId(NodeId index) { return index; }

SymbolId& FileContent::Name(NodeId index) { return m_objects[index].m_name; }

NodeId& FileContent::Child(NodeId index) { return m_objects[index].m_child; }

NodeId& FileContent::Sibling(NodeId index) {
  return m_objects[index].m_sibling;
}

NodeId& FileContent::Definition(NodeId index) {
  return m_objects[index].m_definition;
}

NodeId& FileContent::Parent(NodeId index) { return m_objects[index].m_parent; }

VObjectType FileContent::Type(NodeId index) {
  return (VObjectType)m_objects[index].m_type;
}

unsigned int& FileContent::Line(NodeId index) {
  return m_objects[index].m_line;
}

NodeId FileContent::sl_get(NodeId parent, VObjectType type) {
  if (!m_objects.size()) return 0;
  if (parent > m_objects.size() - 1) return 0;
  VObject current = Object(parent);
  if (current.m_type == type) return parent;
  NodeId id = current.m_child;
  while (id) {
    current = Object(id);
    if (current.m_type == type) {
      return id;
    }
    id = current.m_sibling;
  }
  return InvalidNodeId;
}

NodeId FileContent::sl_parent(NodeId parent, std::vector<VObjectType> types,
                              VObjectType& actualType) {
  if (!m_objects.size()) return 0;
  if (parent > m_objects.size() - 1) return 0;
  VObject current = Object(parent);
  for (auto type : types)
    if (current.m_type == type) {
      actualType = type;
      return parent;
    }
  NodeId id = current.m_parent;
  while (id) {
    current = Object(id);
    for (auto type : types)
      if (current.m_type == type) {
        actualType = type;
        return id;
      }
    id = current.m_parent;
  }
  return InvalidNodeId;
}

NodeId FileContent::sl_parent(NodeId parent, VObjectType type) {
  if (!m_objects.size()) return 0;
  if (parent > m_objects.size() - 1) return 0;
  VObject current = Object(parent);
  if (current.m_type == type) return parent;
  NodeId id = current.m_parent;
  while (id) {
    current = Object(id);
    if (current.m_type == type) {
      return id;
    }
    id = current.m_parent;
  }
  return InvalidNodeId;
}

std::vector<NodeId> FileContent::sl_get_all(NodeId parent, VObjectType type) {
  std::vector<NodeId> objects;
  if (!m_objects.size()) return objects;
  if (parent > m_objects.size() - 1) return objects;
  VObject current = Object(parent);
  if (current.m_type == type) objects.push_back(parent);
  NodeId id = current.m_child;
  while (id) {
    current = Object(id);
    if (current.m_type == type) {
      objects.push_back(id);
    }
    id = current.m_sibling;
  }
  return objects;
}

std::vector<NodeId> FileContent::sl_get_all(NodeId parent,
                                            std::vector<VObjectType>& types) {
  std::vector<NodeId> objects;
  if (!m_objects.size()) return objects;
  if (parent > m_objects.size() - 1) return objects;
  VObject current = Object(parent);
  for (auto type : types) {
    if (current.m_type == type) {
      objects.push_back(parent);
      break;
    }
  }

  NodeId id = current.m_child;
  while (id) {
    current = Object(id);
    for (auto type : types) {
      if (current.m_type == type) {
        objects.push_back(id);
        break;
      }
    }
    id = current.m_sibling;
  }
  return objects;
}

NodeId FileContent::sl_collect(NodeId parent, VObjectType type) {
  if (!m_objects.size()) return 0;
  if (parent > m_objects.size() - 1) return 0;
  VObject current = Object(parent);
  if (current.m_type == type) return parent;
  NodeId id = current.m_child;
  while (id) {
    NodeId idsub = sl_collect(id, type);
    if (idsub != InvalidNodeId) {
      return idsub;
    }
    current = Object(id);
    if (current.m_type == type) {
      return id;
    }
    id = current.m_sibling;
  }
  return InvalidNodeId;
}

std::vector<NodeId> FileContent::sl_collect_all(NodeId parent, VObjectType type,
                                                bool first) {
  std::vector<NodeId> objects;
  if (!m_objects.size()) return objects;
  if (parent > m_objects.size() - 1) return objects;
  VObject current = Object(parent);
  NodeId id = current.m_child;
  if (!id) id = current.m_sibling;
  if (!id) return objects;
  std::stack<NodeId> stack;
  stack.push(id);
  while (stack.size()) {
    id = stack.top();
    stack.pop();
    current = Object(id);
    if (current.m_type == type) {
      objects.push_back(id);
      if (first) return objects;
    }
    if (current.m_sibling) stack.push(current.m_sibling);
    if (current.m_child) stack.push(current.m_child);
  }
  return objects;
}

std::vector<NodeId> FileContent::sl_collect_all(NodeId parent,
                                                std::vector<VObjectType>& types,
                                                bool first) {
  std::vector<NodeId> objects;
  if (!m_objects.size()) return objects;
  if (parent > m_objects.size() - 1) return objects;
  VObject current = Object(parent);
  NodeId id = current.m_child;
  if (!id) id = current.m_sibling;
  if (!id) return objects;
  std::stack<NodeId> stack;
  stack.push(id);
  while (stack.size()) {
    id = stack.top();
    stack.pop();
    current = Object(id);
    // std::cout << "COLLECT:" << current.print (m_symbolTable, id,
    // GetDefinitionFile(id)) << std::endl;
    for (auto type : types) {
      if (current.m_type == type) {
        objects.push_back(id);
        if (first) return objects;
        break;
      }
    }
    if (current.m_sibling) stack.push(current.m_sibling);
    if (current.m_child) stack.push(current.m_child);
  }
  return objects;
}

NodeId FileContent::sl_collect(NodeId parent, VObjectType type,
                               VObjectType stopPoint) {
  NodeId result = InvalidNodeId;
  if (!m_objects.size()) return result;
  if (parent > m_objects.size() - 1) return result;
  VObject current = Object(parent);
  NodeId id = current.m_child;
  if (!id) id = current.m_sibling;
  if (!id) return result;
  std::stack<NodeId> stack;
  stack.push(id);
  while (stack.size()) {
    id = stack.top();
    stack.pop();
    current = Object(id);
    if (current.m_type == type) {
      return id;
    }

    if (current.m_sibling) stack.push(current.m_sibling);

    if (current.m_child) {
      if (stopPoint != current.m_type)
        if (current.m_child) stack.push(current.m_child);
    }
  }
  return result;
}

std::vector<NodeId> FileContent::sl_collect_all(
    NodeId parent, std::vector<VObjectType>& types,
    std::vector<VObjectType>& stopPoints, bool first) {
  std::vector<NodeId> objects;
  if (!m_objects.size()) return objects;
  if (parent > m_objects.size() - 1) return objects;
  VObject current = Object(parent);
  NodeId id = current.m_child;
  if (!id) id = current.m_sibling;
  if (!id) return objects;
  std::stack<NodeId> stack;
  stack.push(id);
  while (stack.size()) {
    id = stack.top();
    stack.pop();
    current = Object(id);
    // std::cout << "COLLECT:" << current.print (m_symbolTable, id,
    // GetDefinitionFile(id)) << std::endl;
    for (auto type : types) {
      if (current.m_type == type) {
        objects.push_back(id);
        if (first) return objects;
        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 objects;
}

bool FileContent::diffTree(std::string& diff, NodeId root, FileContent* oFc,
                           NodeId oroot) {
  diff = "";

  VObject current1 = Object(root);
  NodeId id1 = current1.m_child;
  if (!id1) id1 = current1.m_sibling;

  VObject current2 = oFc->Object(oroot);
  NodeId id2 = current2.m_child;
  if (!id2) id2 = current2.m_sibling;

  if ((id1 && (!id2)) || ((!id1) && id2)) return true;

  std::stack<NodeId> stack1;
  std::stack<NodeId> stack2;
  stack1.push(id1);
  stack2.push(id2);
  while (stack1.size()) {
    if (!stack2.size()) return true;
    id1 = stack1.top();
    id2 = stack2.top();
    stack1.pop();
    stack2.pop();
    current1 = Object(id1);
    current2 = oFc->Object(id2);
    if (current1.m_type != current2.m_type) {
      return true;
    }
    std::string symb1;
    std::string symb2;
    if (current1.m_name) symb1 = Name(id1);
    if (current2.m_name) symb2 = oFc->Name(id2);
    if (current1.m_name || current2.m_name)
      if (symb1 != symb2) return true;

    if (current1.m_sibling) stack1.push(current1.m_sibling);
    if (current1.m_child) stack1.push(current1.m_child);
    if (current2.m_sibling) stack2.push(current2.m_sibling);
    if (current2.m_child) stack2.push(current2.m_child);
  }
  if (stack2.size()) return true;
  return false;
}
