/*
 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:   LibrarySet.cpp
 * Author: alain
 *
 * Created on January 27, 2018, 5:28 PM
 */
#include <vector>
#include <set>
#include <iostream>
#include "../SourceCompile/SymbolTable.h"
#include "../ErrorReporting/ErrorContainer.h"
#include "LibrarySet.h"

using namespace SURELOG;

LibrarySet::LibrarySet() {}

LibrarySet::LibrarySet(const LibrarySet& orig) {}

LibrarySet::~LibrarySet() {}

Library* LibrarySet::getLibrary(std::string libName) {
  for (unsigned int i = 0; i < m_libraries.size(); i++) {
    if (m_libraries[i].getName() == libName) return &m_libraries[i];
  }
  return NULL;
}

Library* LibrarySet::getLibrary(SymbolId fileId) {
  Library* lib = NULL;
  for (unsigned int i = 0; i < m_libraries.size(); i++) {
    if (m_libraries[i].isMember(fileId)) {
      lib = &m_libraries[i];
      break;
    }
  }
  if (lib == NULL) {
    getLibrary("work")->addFileId(fileId);
    lib = getLibrary("work");
  }
  return lib;
}

std::string LibrarySet::report(SymbolTable* symbols) {
  std::string report;
  for (unsigned int i = 0; i < m_libraries.size(); i++) {
    report += m_libraries[i].report(symbols) + "\n";
  }
  return report;
}

void LibrarySet::checkErrors(SymbolTable* symbols, ErrorContainer* errors) {
  std::map<SymbolId, std::string> fileSet;
  for (unsigned int i = 0; i < m_libraries.size(); i++) {
    for (auto file : m_libraries[i].getFiles()) {
      std::map<SymbolId, std::string>::iterator itr = fileSet.find(file);
      if (itr == fileSet.end()) {
        fileSet.insert(std::make_pair(file, m_libraries[i].getName()));
      } else {
        Location loc1(symbols->registerSymbol((*itr).second + ", " +
                                              m_libraries[i].getName()));
        Location loc2(file);
        Error err(ErrorDefinition::LIB_FILE_MAPS_TO_MULTIPLE_LIBS, loc1, loc2);
        errors->addError(err);
      }
    }
  }
}
