#include<iostream>
#include<algorithm>

#include "nlsr_adl.hpp"
#include "nlsr_adjacent.hpp"
#include "nlsr.hpp"

Adl::Adl(){
}

Adl::~Adl(){

}

static bool
adjacent_compare(Adjacent& adj1, Adjacent& adj2){
	return adj1.getAdjacentName()==adj2.getAdjacentName();
}

int
Adl::insert(Adjacent& adj){
	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
								adjList.end(),	
   								bind(&adjacent_compare, _1, adj));
	if ( it != adjList.end() ){
		return -1;
	}
	adjList.push_back(adj);
	return 0;
}
int
Adl::updateAdjacentStatus(string adjName, int s){
	Adjacent adj(adjName);
	
	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
								adjList.end(),	
   								bind(&adjacent_compare, _1, adj));

	if( it == adjList.end()){
		return -1;
	}

	(*it).setStatus(s);
	return 0;
	

}

Adjacent 
Adl::getAdjacent(string adjName)
{
	Adjacent adj(adjName);
	
	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
								adjList.end(),	
   								bind(&adjacent_compare, _1, adj));

	if( it != adjList.end()){
		return (*it);
	}

	return adj;
}

int 
Adl::updateAdjacentLinkCost(string adjName, double lc){
	Adjacent adj(adjName);
	
	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
								adjList.end(),	
   								bind(&adjacent_compare, _1, adj));

	if( it == adjList.end()){
		return -1;
	}

	(*it).setLinkCost(lc);
	return 0;

}

bool 
Adl::isNeighbor(string adjName){
	Adjacent adj(adjName);
	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
								adjList.end(),	
   								bind(&adjacent_compare, _1, adj));

	if( it == adjList.end()){
		return false;
	}

	return true;
}

void 
Adl::incrementTimedOutInterestCount(string& neighbor){
	Adjacent adj(neighbor);
	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
								adjList.end(),	
   								bind(&adjacent_compare, _1, adj));

	if( it == adjList.end()){
		return ;
	}

	(*it).setInterestTimedOutNo((*it).getInterestTimedOutNo()+1);

}

void 
Adl::setTimedOutInterestCount(string& neighbor, int count){
	Adjacent adj(neighbor);
	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
								adjList.end(),	
   								bind(&adjacent_compare, _1, adj));

	if( it != adjList.end()){
		(*it).setInterestTimedOutNo(count);
	}
}

int
Adl::getTimedOutInterestCount(string& neighbor)
{
	Adjacent adj(neighbor);
	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
								adjList.end(),	
   								bind(&adjacent_compare, _1, adj));

	if( it == adjList.end()){
		return -1;
	}

	return (*it).getInterestTimedOutNo();
}

int 
Adl::getStatusOfNeighbor(string& neighbor)
{
	Adjacent adj(neighbor);
	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
								adjList.end(),	
   								bind(&adjacent_compare, _1, adj));

	if( it == adjList.end()){
		return -1;
	}

	return (*it).getStatus();
}

void
Adl::setStatusOfNeighbor(string& neighbor, int status)
{
	Adjacent adj(neighbor);
	std::list<Adjacent >::iterator it = std::find_if( adjList.begin(), 
								adjList.end(),	
   								bind(&adjacent_compare, _1, adj));

	if( it != adjList.end()){
		(*it).setStatus(status);
	}
}

std::list<Adjacent>& 
Adl::getAdjList(){
	return adjList;
}

bool
Adl::isAdjLsaBuildable(nlsr& pnlsr)
{
	int nbrCount=0;
	for( std::list<Adjacent>::iterator it=adjList.begin(); 
	                                                   it!= adjList.end() ; it++)
	{
		if ( ((*it).getStatus() == 1 ) )
		{
			nbrCount++;
		}
		else
		{
			if ( (*it).getInterestTimedOutNo() >= 
				                       pnlsr.getConfParameter().getInterestRetryNumber())
			{
					nbrCount++;
			}
		} 
	}

	if( nbrCount == adjList.size())
	{
		return true;
	}

	return false;
}

int 
Adl::getNumOfActiveNeighbor()
{
	int actNbrCount=0;
	for( std::list<Adjacent>::iterator it=adjList.begin(); 
	                                                   it!= adjList.end() ; it++)
	{
		if ( ((*it).getStatus() == 1 ) )
		{
			actNbrCount++;
		}
	}

	return actNbrCount;
}

// used for debugging purpose
void
Adl::printAdl(){
	for( std::list<Adjacent>::iterator it=adjList.begin(); it!= adjList.end() ; it++){
		cout<< (*it) <<endl;
	}
}
