/*
 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:   ModuleDefinition.cpp
 * Author: alain
 *
 * Created on October 20, 2017, 10:29 PM
 */

#include "SourceCompile/SymbolTable.h"
#include "Library/Library.h"
#include "Design/FileContent.h"
#include "Design/ModuleDefinition.h"

using namespace SURELOG;

ModuleDefinition::ModuleDefinition(FileContent* fileContent, NodeId nodeId,
                                   std::string& name)
    : DesignComponent(fileContent), m_name(name) {
  if (fileContent) {
    addFileContent(fileContent, nodeId);
  }
}

bool ModuleDefinition::isInstance() {
  VObjectType type = getType();
  if ((type == VObjectType::slN_input_gate_instance) ||
      (type == VObjectType::slModule_declaration) ||
      (type == VObjectType::slUdp_declaration))
    return true;
  return false;
}

ModuleDefinition::~ModuleDefinition() {}

ModuleDefinition* ModuleDefinitionFactory::newModuleDefinition(
    FileContent* fileContent, NodeId nodeId, std::string name) {
  return new ModuleDefinition(fileContent, nodeId, name);
}

unsigned int ModuleDefinition::getSize() {
  if (m_fileContents.size()) {
    return 0;
  }
  unsigned int size = 0;
  for (unsigned int i = 0; i < m_fileContents.size(); i++) {
    NodeId end = m_nodeIds[i];
    NodeId begin = m_fileContents[i]->Child(end);
    size += (end - begin);
  }
  return size;
}

void ModuleDefinition::insertModPort(SymbolId modport, Signal& signal) {
  ModPortSignalMap::iterator itr = m_modportSignalMap.find(modport);
  if (itr == m_modportSignalMap.end()) {
    std::vector<Signal> signals;
    signals.push_back(signal);
    m_modportSignalMap.insert(std::make_pair(modport, signals));
  } else {
    (*itr).second.push_back(signal);
  }
}

Signal* ModuleDefinition::getModPortSignal(SymbolId modport, NodeId port) {
  ModPortSignalMap::iterator itr = m_modportSignalMap.find(modport);
  if (itr == m_modportSignalMap.end()) {
    return NULL;
  } else {
    for (auto& sig : (*itr).second) {
      if (sig.getNodeId() == port) {
        return &sig;
      }
    }
  }
  return NULL;
}

void ModuleDefinition::insertModPort(SymbolId modport, ClockingBlock& cb) {
  ModPortClockingBlockMap::iterator itr =
      m_modportClockingBlockMap.find(modport);
  if (itr == m_modportClockingBlockMap.end()) {
    std::vector<ClockingBlock> cbs;
    cbs.push_back(cb);
    m_modportClockingBlockMap.insert(std::make_pair(modport, cbs));
  } else {
    (*itr).second.push_back(cb);
  }
}

ClockingBlock* ModuleDefinition::getModPortClockingBlock(SymbolId modport,
                                                         NodeId port) {
  ModPortClockingBlockMap::iterator itr =
      m_modportClockingBlockMap.find(modport);
  if (itr == m_modportClockingBlockMap.end()) {
    return NULL;
  } else {
    for (auto& cb : (*itr).second) {
      if (cb.getNodeId() == port) {
        return &cb;
      }
    }
  }
  return NULL;
}

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