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