/*
 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:   LoopCheck.cpp
 * Author: alain
 * 
 * Created on May 2, 2017, 8:14 PM
 */

#include <queue>
#include <set>
#include "SymbolTable.h"
#include "LoopCheck.h"

using namespace SURELOG;

LoopCheck::LoopCheck () { }

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

LoopCheck::~LoopCheck () { 
  for (auto itr : m_nodes) 
    {
      delete itr.second;  
    }
}

void LoopCheck::clear() {
   for (auto itr : m_nodes) 
    {
      delete itr.second;  
    }
   m_nodes.clear();
}

bool LoopCheck::addEdge(SymbolId from, SymbolId to) {
  // Create Graph
  std::map<SymbolId, Node*>::iterator fromIt = m_nodes.find(from);
  std::map<SymbolId, Node*>::iterator toIt = m_nodes.find(to);
  Node* nodeFrom = NULL;
  Node* nodeTo = NULL;
  if (fromIt == m_nodes.end()) 
    {
      nodeFrom = new Node(from);
      m_nodes.insert(std::make_pair(from, nodeFrom));
    }
  else
    {
      nodeFrom = (*fromIt).second;
    }
  if (toIt == m_nodes.end()) 
    {
      nodeTo = new Node(to);
      m_nodes.insert(std::make_pair(to, nodeTo));
    }
  else
    {
      nodeTo = (*toIt).second;
    }
  nodeFrom->m_toList.insert(nodeTo);
  
  for (auto itr : m_nodes) 
    {
      itr.second->m_visited = false;  
    }
  
  // BFS 
  std::queue<Node*> queue;
  queue.push(nodeTo);
  nodeTo->m_visited = true;
  while (!queue.empty ()) 
    {
      Node* tmp = queue.front(); queue.pop();
      tmp->m_visited = true;
      for (auto next : tmp->m_toList)
        {
          if (next->m_visited)
            return true;
          else
            {
              queue.push(next);
            }
        }
    }
  
  return false;
}

std::vector<SymbolId> LoopCheck::reportLoop() {
  std::vector<SymbolId> loop;
  for (auto itr : m_nodes) 
    {
      if (itr.second->m_visited) 
        {
          loop.push_back (itr.first);
        }
    }
  return loop;
}


