#include <list>
#include <utility>
#include "nlsr_npte.hpp"
#include "nlsr_rte.hpp"
#include "nlsr_nexthop.hpp"

using namespace std;

void
Npte::generateNhlfromRteList()
{
	nhl.resetNhl();
	for( std::list<RoutingTableEntry>::iterator it=rteList.begin();
	                                                   it != rteList.end(); ++it )
	{
		for(std::list< NextHop >::iterator nhit=(*it).getNhl().getNextHopList().begin();
		                         nhit != (*it).getNhl().getNextHopList().end(); ++nhit)
		{
			nhl.addNextHop((*nhit));
		}
	}
}



static bool
rteCompare(RoutingTableEntry& rte, string& destRouter){
	return rte.getDestination()==destRouter;
}

void 
Npte::removeRoutingTableEntry(RoutingTableEntry& rte)
{
	std::list<RoutingTableEntry >::iterator it = std::find_if( rteList.begin(), 
									rteList.end(),	
   								bind(&rteCompare, _1, rte.getDestination()));
  if ( it != rteList.end() )
  {
  		rteList.erase(it);
  }
}

void 
Npte::addRoutingTableEntry(RoutingTableEntry &rte)
{
	std::list<RoutingTableEntry >::iterator it = std::find_if( rteList.begin(), 
									rteList.end(),	
   								bind(&rteCompare, _1, rte.getDestination()));
  if ( it == rteList.end() )
  {
  		rteList.push_back(rte);
  }
  else
  {
  		(*it).getNhl().resetNhl(); // reseting existing routing table's next hop
  		for(std::list< NextHop >::iterator nhit=rte.getNhl().getNextHopList().begin();
		                         nhit != rte.getNhl().getNextHopList().end(); ++nhit)
		{
			(*it).getNhl().addNextHop((*nhit));
		}
  }
}

//debugging purpose
ostream&
operator<<(ostream& os, Npte& npte)
{
	os<<"Name: "<<npte.getNamePrefix()<<endl;
	std::list<RoutingTableEntry> rteList=npte.getRteList();
	for(std::list<RoutingTableEntry >::iterator it=rteList.begin(); 
	                                                      it !=rteList.end(); ++it)
	{
		cout<<(*it);
	}
	os<<npte.getNhl();

	return os;
}
