#include <iostream>
#include <cmath>
#include "nlsr_lsdb.hpp"
#include "nlsr_rtc.hpp"
#include "nlsr_map.hpp"
#include "nlsr_lsa.hpp"
#include "nlsr_nexthop.hpp"
#include "nlsr.hpp"

namespace nlsr {

using namespace std;

void 
RoutingTableCalculator::allocateAdjMatrix()
{
	adjMatrix = new double*[numOfRouter];
	for(int i = 0; i < numOfRouter; ++i) 
	{
    adjMatrix[i] = new double[numOfRouter];
	}
}

void 
RoutingTableCalculator::initMatrix()
{
	for(int i=0;i<numOfRouter;i++)
	{
		for(int j=0;j<numOfRouter;j++)
			adjMatrix[i][j]=0;
	}
}

void
RoutingTableCalculator::makeAdjMatrix(Nlsr& pnlsr, Map pMap)
{
	std::list<AdjLsa> adjLsdb=pnlsr.getLsdb().getAdjLsdb();
	for( std::list<AdjLsa>::iterator it=adjLsdb.begin(); 
	                                                 it!= adjLsdb.end() ; it++)
	{
		string linkStartRouter=(*it).getOrigRouter();
		int row=pMap.getMappingNoByRouterName(linkStartRouter);
		std::list<Adjacent> adl=(*it).getAdl().getAdjList();
		for( std::list<Adjacent>::iterator itAdl=adl.begin(); 
																								itAdl!= adl.end() ; itAdl++)
		{
			string linkEndRouter=(*itAdl).getAdjacentName();
			int col=pMap.getMappingNoByRouterName(linkEndRouter);
			double cost=(*itAdl).getLinkCost();
			if ( (row >= 0 && row<numOfRouter) && (col >= 0 && col<numOfRouter) )
			{
				adjMatrix[row][col]=cost;
			}
		}
		
	}
}

void
RoutingTableCalculator::printAdjMatrix()
{
	for(int i=0;i<numOfRouter;i++)
	{
		for(int j=0;j<numOfRouter;j++)
			printf("%f ",adjMatrix[i][j]);
		printf("\n");
	}
}

void 
RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
{
	for ( int i = 0; i < numOfRouter; i++ ){
		if ( i == link ){
			adjMatrix[source][i]=linkCost;
		}
		else{
			adjMatrix[source][i]=0;
		}
	}
}

int 
RoutingTableCalculator::getNumOfLinkfromAdjMatrix(int sRouter)
{
	int noLink=0;
	for(int i=0;i<numOfRouter;i++)
	{	
		if ( adjMatrix[sRouter][i] > 0 )
		{
			noLink++;
		}
	}
	return noLink;
}

void 
RoutingTableCalculator::getLinksFromAdjMatrix(int *links, 
                                                 double *linkCosts, int source)
{
	int j=0;
	for (int i=0; i <numOfRouter; i++)
	{
		if ( adjMatrix[source][i] > 0 )
		{
			links[j]=i;
			linkCosts[j]=adjMatrix[source][i];
			j++;
		}
	}
}

void 
RoutingTableCalculator::freeAdjMatrix()
{
	for(int i = 0; i < numOfRouter; ++i) 
	{
    	delete [] adjMatrix[i];
	}
	delete [] adjMatrix;
}


void 
RoutingTableCalculator::allocateLinks()
{
	links=new int[vNoLink];
}

void RoutingTableCalculator::allocateLinkCosts()
{
	linkCosts=new double[vNoLink];
}


void 
RoutingTableCalculator::freeLinks()
{
	delete [] links;
}
void 
RoutingTableCalculator::freeLinksCosts()
{
	delete [] linkCosts;
}

void
LinkStateRoutingTableCalculator::calculatePath(Map& pMap, 
                                                  RoutingTable& rt, Nlsr& pnlsr)
{
	cout<<"LinkStateRoutingTableCalculator::calculatePath Called"<<endl;
	allocateAdjMatrix();
	initMatrix();
	makeAdjMatrix(pnlsr,pMap);
	cout<<pMap;
	printAdjMatrix();
	string routerName=pnlsr.getConfParameter().getRouterPrefix();
	int sourceRouter=pMap.getMappingNoByRouterName(routerName);
	int noLink=getNumOfLinkfromAdjMatrix(sourceRouter);
	allocateParent();
	allocateDistance();

	if ( pnlsr.getConfParameter().getMaxFacesPerPrefix() == 1 )
	{
		// Single Path
		doDijkstraPathCalculation(sourceRouter);
		// print all ls path -- debugging purpose
		printAllLsPath(sourceRouter);
		// update routing table
		addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
	}
	else
	{
		// Multi Path
		setNoLink(getNumOfLinkfromAdjMatrix(sourceRouter));
		allocateLinks();
		allocateLinkCosts();

		getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
		for (int i=0 ; i < vNoLink; i++)
		{
			
			adjustAdMatrix(sourceRouter,links[i], linkCosts[i]);
			printAdjMatrix();
			doDijkstraPathCalculation(sourceRouter);
			// print all ls path -- debugging purpose
			printAllLsPath(sourceRouter);
			//update routing table
			addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
		}
		
		freeLinks();
	  freeLinksCosts();
	}

	freeParent();
	freeDistance();
	freeAdjMatrix();
}

void 
LinkStateRoutingTableCalculator::doDijkstraPathCalculation(int sourceRouter)
{
	int i;
	int v,u;
	int *Q=new int[numOfRouter];
	int head=0;
	/* Initiate the Parent */
	for (i = 0 ; i < numOfRouter; i++){
		parent[i]=EMPTY_PARENT;
		distance[i]=INF_DISTANCE;
		Q[i]=i;
	} 

	if ( sourceRouter != NO_MAPPING_NUM ){
		distance[sourceRouter]=0;
		sortQueueByDistance(Q,distance,head,numOfRouter);

		while (head < numOfRouter )
		{
			u=Q[head];
			if(distance[u] == INF_DISTANCE)
			{
				break;
			}

			for(v=0 ; v <numOfRouter; v++)
			{
				if( adjMatrix[u][v] > 0 )
				{
					if ( isNotExplored(Q,v,head+1,numOfRouter) )
					{
						if( distance[u] + adjMatrix[u][v] <  distance[v])
						{
							distance[v]=distance[u] + adjMatrix[u][v] ;
							parent[v]=u;
						}	

					}

				}

			}

			head++;
			sortQueueByDistance(Q,distance,head,numOfRouter);
		}
	}
	delete [] Q;
}

void 
LinkStateRoutingTableCalculator::addAllLsNextHopsToRoutingTable(Nlsr& pnlsr,
																 RoutingTable& rt, Map& pMap, int sourceRouter)
{
	cout<<"LinkStateRoutingTableCalculator::addAllNextHopsToRoutingTable Called";
	cout<<endl;
	for(int i=0; i < numOfRouter ; i++)
	{
		if ( i!= sourceRouter )
		{
			int nextHopRouter=getLsNextHop(i,sourceRouter);
			double routeCost=distance[i];
			string nextHopRouterName=pMap.getRouterNameByMappingNo(nextHopRouter);
			int nxtHopFace=
              pnlsr.getAdl().getAdjacent(nextHopRouterName).getConnectingFace();
			cout<<"Dest Router: "<<pMap.getRouterNameByMappingNo(i)<<endl;
			cout<<"Next hop Router: "<<nextHopRouterName<<endl;
			cout<<"Next hop Face: "<<nxtHopFace<<endl;
			cout<<"Route Cost: "<<routeCost<<endl;
			cout<<endl;
			// Add next hop to routing table
			NextHop nh(nxtHopFace,routeCost);
			rt.addNextHop(pMap.getRouterNameByMappingNo(i),nh);
			
		}
	}
}

int 
LinkStateRoutingTableCalculator::getLsNextHop(int dest, int source)
{
	int nextHop;
	while ( parent[dest] != EMPTY_PARENT )
	{
		nextHop=dest;
		dest=parent[dest];

	}

	if ( dest != source )
	{
		nextHop=NO_NEXT_HOP;	
	}

	return nextHop;
}

void
LinkStateRoutingTableCalculator::printAllLsPath(int sourceRouter)
{
	cout<<"LinkStateRoutingTableCalculator::printAllLsPath Called"<<endl;
	cout<<"Source Router: "<<sourceRouter<<endl;
	for(int i=0; i < numOfRouter ; i++)
	{
		if ( i!= sourceRouter )
		{
			printLsPath(i);
			cout<<endl;
		}
	}
}

void
LinkStateRoutingTableCalculator::printLsPath(int destRouter)
{
	if (parent[destRouter] != EMPTY_PARENT )
	{
		printLsPath(parent[destRouter]);
	}

	cout<<" "<<destRouter;
}

void 
LinkStateRoutingTableCalculator::sortQueueByDistance(int *Q,
                                             double *dist,int start,int element)
{
	for ( int i=start ; i < element ; i ++) 
	{
		for( int j=i+1; j<element; j ++)
		{
			if (dist[Q[j]] < dist[Q[i]])
			{
				int tempU=Q[j];
				Q[j]=Q[i];
				Q[i]=tempU;
			}
		}
	}

}

int 
LinkStateRoutingTableCalculator::isNotExplored(int *Q, 
                                                   int u,int start, int element)
{
	int ret=0;
	for(int i=start; i< element; i++)
	{
		if ( Q[i] == u )
		{
			ret=1;
			break;
		}
	}
	return ret;
}

void 
LinkStateRoutingTableCalculator::allocateParent()
{
	parent=new int[numOfRouter];
}

void 
LinkStateRoutingTableCalculator::allocateDistance()
{
	distance= new double[numOfRouter];
}

void 
LinkStateRoutingTableCalculator::freeParent()
{
	delete [] parent;
}

void LinkStateRoutingTableCalculator::freeDistance()
{
	delete [] distance;
}



void
HypRoutingTableCalculator::calculatePath(Map& pMap, 
                                                  RoutingTable& rt, Nlsr& pnlsr)
{
	makeAdjMatrix(pnlsr,pMap);
	string routerName=pnlsr.getConfParameter().getRouterPrefix();
	int sourceRouter=pMap.getMappingNoByRouterName(routerName);
	int noLink=getNumOfLinkfromAdjMatrix(sourceRouter);
	setNoLink(noLink);
	allocateLinks();
	allocateLinkCosts();

	getLinksFromAdjMatrix(links, linkCosts, sourceRouter);

	for(int i=0 ; i < numOfRouter ; ++i)
	{
			int k=0;
			if ( i != sourceRouter)
			{
				allocateLinkFaces();
				allocateDistanceToNeighbor();
				allocateDistFromNbrToDest();

				for(int j=0; j<vNoLink; j++)
				{
					string nextHopRouterName=pMap.getRouterNameByMappingNo(links[j]);
					int nextHopFace=
              pnlsr.getAdl().getAdjacent(nextHopRouterName).getConnectingFace();
          double distToNbr=getHyperbolicDistance(pnlsr,pMap,
                                                         sourceRouter,links[j]);
					double distToDestFromNbr=getHyperbolicDistance(pnlsr, 
					                                                    pMap,links[j],i);
					if ( distToDestFromNbr >= 0 )
					{
							linkFaces[k] = nextHopFace;
							distanceToNeighbor[k] = distToNbr;
							distFromNbrToDest[k] = distToDestFromNbr;
							k++;
					}
				}

				addHypNextHopsToRoutingTable(pnlsr,pMap,rt,k,i);

				freeLinkFaces();
				freeDistanceToNeighbor();
				freeDistFromNbrToDest();	
			}
	}

	freeLinks();
	freeLinksCosts();
	freeAdjMatrix();
}

void
HypRoutingTableCalculator::addHypNextHopsToRoutingTable(Nlsr& pnlsr,Map& pMap,
                                        RoutingTable& rt, int noFaces, int dest)
{
	for(int i=0 ; i < noFaces ; ++i)
	{
		string destRouter=pMap.getRouterNameByMappingNo(dest);
		NextHop nh(linkFaces[i],distFromNbrToDest[i]);
		rt.addNextHop(destRouter,nh);
		if( isDryRun == 1 )
		{
			rt.addNextHopToDryTable(destRouter,nh);
		}
	}
	
} 

double 
HypRoutingTableCalculator::getHyperbolicDistance(Nlsr& pnlsr,
                                                  Map& pMap, int src, int dest)
{
	double distance=0.0;

	string srcRouterKey=pMap.getRouterNameByMappingNo(src)+"/3";
	string destRouterKey=pMap.getRouterNameByMappingNo(dest)+"/3";

	double srcRadius=(pnlsr.getLsdb().getCorLsa(srcRouterKey).first).getCorRadius();
	double srcTheta=(pnlsr.getLsdb().getCorLsa(srcRouterKey).first).getCorTheta();

	double destRadius=(pnlsr.getLsdb().getCorLsa(destRouterKey).first).getCorRadius();
	double destTheta=(pnlsr.getLsdb().getCorLsa(destRouterKey).first).getCorTheta();


	double diffTheta = fabs (srcTheta - destTheta);

	if (diffTheta > MATH_PI)
	{
		diffTheta = 2 * MATH_PI - diffTheta; 	
	}

	if ( srcRadius != -1 && destRadius != -1 )
	{
		if (diffTheta == 0)
			distance = fabs (srcRadius - destRadius); 
		else
			distance = acosh((cosh(srcRadius)*cosh(destRadius))-
					(sinh(srcRadius)*sinh(destRadius)*cos(diffTheta)));
	}else
	{
		distance = -1;
	}

	return distance;
}

void 
HypRoutingTableCalculator::allocateLinkFaces()
{
	linkFaces=new int[vNoLink];
}

void 
HypRoutingTableCalculator::allocateDistanceToNeighbor()
{
	distanceToNeighbor=new double[vNoLink];
}

void 
HypRoutingTableCalculator::allocateDistFromNbrToDest()
{
	distFromNbrToDest=new double[vNoLink];
}

void 
HypRoutingTableCalculator::freeLinkFaces()
{
	delete [] linkFaces;
}

void 
HypRoutingTableCalculator::freeDistanceToNeighbor()
{
	delete [] distanceToNeighbor;
}

void 
HypRoutingTableCalculator::freeDistFromNbrToDest()
{
	delete [] distFromNbrToDest;
}

}//namespace nlsr
