#include <list>
#include <utility>
#include <algorithm>

#include "nlsr_npt.hpp"
#include "nlsr_npte.hpp"
#include "nlsr.hpp"

using namespace std;

static bool
npteCompare(Npte& npte, string& name){
	return npte.getNamePrefix()==name;
}

// Following two methods will update FIB with response to change in NPT

void 
Npt::addNpte(string name, RoutingTableEntry& rte, nlsr& pnlsr)
{
	std::list<Npte >::iterator it = std::find_if( npteList.begin(), 
									               npteList.end(), bind(&npteCompare, _1, name));
   								
  if ( it == npteList.end() )
  {
  		Npte newEntry(	name);
  		newEntry.addRoutingTableEntry(rte);
  		newEntry.generateNhlfromRteList();
  		npteList.push_back(newEntry);
  		// update FIB here with nhl list newEntry.getNhl()
  		pnlsr.getFib().updateFib(name,newEntry.getNhl(),
  		                         pnlsr.getConfParameter().getMaxFacesPerPrefix());
  }	
  else
  {
  		(*it).addRoutingTableEntry(rte);
  		(*it).generateNhlfromRteList();
  		// update FIB here with nhl list from (*it).getNhl()
  		pnlsr.getFib().updateFib(name,(*it).getNhl() ,
  		                         pnlsr.getConfParameter().getMaxFacesPerPrefix());
  }
}

void 
Npt::removeNpte(string name, RoutingTableEntry& rte, nlsr& pnlsr)
{
	std::list<Npte >::iterator it = std::find_if( npteList.begin(), 
									               npteList.end(), bind(&npteCompare, _1, name));
  if ( it != npteList.end() )
  {
  		string destRouter=rte.getDestination();
  		
  		(*it).removeRoutingTableEntry(rte);
  		if ( ((*it).getRteListSize() == 0 ) &&
  		        (!pnlsr.getLsdb().doesLsaExist(destRouter+"/1",1) ) && 
  		        (!pnlsr.getLsdb().doesLsaExist(destRouter+"/2",2) ) &&
  		        (!pnlsr.getLsdb().doesLsaExist(destRouter+"/3",3) )   ) 
  		{
  			npteList.erase(it); // remove entry from NPT
  			// remove FIB entry with this name
  			pnlsr.getFib().removeFromFib(name);
  			
  		}
  		else
  		{
  			(*it).generateNhlfromRteList();
  			// update FIB entry with new NHL
  			pnlsr.getFib().updateFib(name,(*it).getNhl(),
  			                         pnlsr.getConfParameter().getMaxFacesPerPrefix());
  		}
  }
}


void 
Npt::addNpte(string name, string destRouter, nlsr& pnlsr)
{
	std::pair<RoutingTableEntry& , bool> rteCheck= 
	            pnlsr.getRoutingTable().findRoutingTableEntry(destRouter);
	if(rteCheck.second)
	{
		addNpte(name,rteCheck.first,pnlsr);
	}
	else
	{
		RoutingTableEntry rte(destRouter);
		addNpte(name, rte,pnlsr);
	}
	
}

void 
Npt::removeNpte(string name, string destRouter, nlsr& pnlsr)
{
	std::pair<RoutingTableEntry& , bool> rteCheck= 
	            pnlsr.getRoutingTable().findRoutingTableEntry(destRouter);
	if(rteCheck.second)
	{
		removeNpte(name,rteCheck.first,pnlsr);
	}
	else
	{
		RoutingTableEntry rte(destRouter);
		removeNpte(name, rte,pnlsr);
	}
}

void 
Npt::updateNptWithNewRoute(nlsr& pnlsr)
{
	for(std::list<Npte >::iterator it=npteList.begin(); it!=npteList.end(); ++it)
	{
		std::list<RoutingTableEntry> rteList=(*it).getRteList();
		for(std::list<RoutingTableEntry >::iterator rteit=rteList.begin(); 
	                                               rteit !=rteList.end(); ++rteit)
	  {
	  		std::pair<RoutingTableEntry& , bool> rteCheck=
	  		 pnlsr.getRoutingTable().findRoutingTableEntry((*rteit).getDestination());
	  		if(rteCheck.second)
			{
				addNpte((*it).getNamePrefix(),rteCheck.first,pnlsr);
			}
			else
			{
				RoutingTableEntry rte((*rteit).getDestination());
				addNpte((*it).getNamePrefix(), rte,pnlsr);
			} 
	  }
	}
}

void
Npt::printNpt()
{
	cout<<"----------------NPT----------------------"<<endl;
	for(std::list<Npte >::iterator it=npteList.begin(); it!=npteList.end(); ++it)
	{
		cout <<(*it)<<endl;
	}
}
