#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(pnlsr, name,newEntry.getNhl(),
  		                         pnlsr.getConfParameter().getMaxFacesPerPrefix());
  }	
  else
  {
  		(*it).addRoutingTableEntry(rte);
  		(*it).generateNhlfromRteList();
  		// update FIB here with nhl list from (*it).getNhl()
  		pnlsr.getFib().updateFib(pnlsr, 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(pnlsr,name);
  			
  		}
  		else
  		{
  			(*it).generateNhlfromRteList();
  			// update FIB entry with new NHL
  			pnlsr.getFib().updateFib(pnlsr, 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;
	}
}
