#include<iostream>
#include<string>
#include<list>

#include "nlsr_rt.hpp"
#include "nlsr.hpp"
#include "nlsr_map.hpp"
#include "nlsr_rtc.hpp"
#include "nlsr_rte.hpp"
#include "nlsr_npt.hpp"

namespace nlsr
{

    using namespace std;

    void
    RoutingTable::calculate(Nlsr& pnlsr)
    {
        //debugging purpose
        pnlsr.getNpt().printNpt();
        if ( 	pnlsr.getIsRoutingTableCalculating() == 0 )
        {
            pnlsr.setIsRoutingTableCalculating(1); //setting routing table calculation
            if ( pnlsr.getLsdb().doesLsaExist(
                        pnlsr.getConfParameter().getRouterPrefix()+"/"+"2",2) )
            {
                if(pnlsr.getIsBuildAdjLsaSheduled() != 1)
                {
                    cout<<"CLearing old routing table ....."<<endl;
                    clearRoutingTable();
                    clearDryRoutingTable(); // for dry run options
                    // calculate Link State routing
                    if( (pnlsr.getConfParameter().getIsHyperbolicCalc() == 0 )
                            || (pnlsr.getConfParameter().getIsHyperbolicCalc() == 2 ) )
                    {
                        calculateLsRoutingTable(pnlsr);
                    }
                    //calculate hyperbolic routing
                    if ( pnlsr.getConfParameter().getIsHyperbolicCalc() == 1 )
                    {
                        calculateHypRoutingTable(pnlsr);
                    }
                    //calculate dry hyperbolic routing
                    if ( pnlsr.getConfParameter().getIsHyperbolicCalc() == 2 )
                    {
                        calculateHypDryRoutingTable(pnlsr);
                    }
                    //need to update NPT here
                    pnlsr.getNpt().updateNptWithNewRoute(pnlsr);
                    //debugging purpose
                    printRoutingTable();
                    pnlsr.getNpt().printNpt();
                    pnlsr.getFib().printFib();
                    //debugging purpose end
                }
                else
                {
                    cout<<"Adjacency building is scheduled, so ";
                    cout<<"routing table can not be calculated :("<<endl;
                }
            }
            else
            {
                cout<<"No Adj LSA of router itself,";
                cout<<	" so Routing table can not be calculated :("<<endl;
                clearRoutingTable();
                clearDryRoutingTable(); // for dry run options
                // need to update NPT here
                pnlsr.getNpt().updateNptWithNewRoute(pnlsr);
                //debugging purpose
                printRoutingTable();
                pnlsr.getNpt().printNpt();
                pnlsr.getFib().printFib();
                //debugging purpose end
            }
            pnlsr.setIsRouteCalculationScheduled(0); //clear scheduled flag
            pnlsr.setIsRoutingTableCalculating(0); //unsetting routing table calculation
        }
        else
        {
            scheduleRoutingTableCalculation(pnlsr);
        }
    }


    void
    RoutingTable::calculateLsRoutingTable(Nlsr& pnlsr)
    {
        cout<<"RoutingTable::calculateLsRoutingTable Called"<<endl;
        Map vMap;
        vMap.createMapFromAdjLsdb(pnlsr);
        int numOfRouter=vMap.getMapSize();
        LinkStateRoutingTableCalculator lsrtc(numOfRouter);
        lsrtc.calculatePath(vMap,boost::ref(*this),pnlsr);
    }

    void
    RoutingTable::calculateHypRoutingTable(Nlsr& pnlsr)
    {
        Map vMap;
        vMap.createMapFromAdjLsdb(pnlsr);
        int numOfRouter=vMap.getMapSize();
        HypRoutingTableCalculator hrtc(numOfRouter,0);
        hrtc.calculatePath(vMap,boost::ref(*this),pnlsr);
    }

    void
    RoutingTable::calculateHypDryRoutingTable(Nlsr& pnlsr)
    {
        Map vMap;
        vMap.createMapFromAdjLsdb(pnlsr);
        int numOfRouter=vMap.getMapSize();
        HypRoutingTableCalculator hrtc(numOfRouter,1);
        hrtc.calculatePath(vMap,boost::ref(*this),pnlsr);
    }

    void
    RoutingTable::scheduleRoutingTableCalculation(Nlsr& pnlsr)
    {
        if ( pnlsr.getIsRouteCalculationScheduled() != 1 )
        {
            pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(15),
                                               ndn::bind(&RoutingTable::calculate,this,boost::ref(pnlsr)));
            pnlsr.setIsRouteCalculationScheduled(1);
        }
    }

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

// function related to manipulation of routing table
    void
    RoutingTable::addNextHop(string destRouter, NextHop& nh)
    {
        std::pair<RoutingTableEntry&, bool> rte=findRoutingTableEntry(destRouter);
        if( !rte.second )
        {
            RoutingTableEntry rte(destRouter);
            rte.getNhl().addNextHop(nh);
            rTable.push_back(rte);
        }
        else
        {
            (rte.first).getNhl().addNextHop(nh);
        }
    }

    std::pair<RoutingTableEntry&, bool>
    RoutingTable::findRoutingTableEntry(string destRouter)
    {
        std::list<RoutingTableEntry >::iterator it = std::find_if( rTable.begin(),
                rTable.end(),
                bind(&routingTableEntryCompare, _1, destRouter));
        if ( it != rTable.end() )
        {
            return std::make_pair(boost::ref((*it)),true);
        }
        RoutingTableEntry rteEmpty;
        return std::make_pair(boost::ref(rteEmpty),false);
    }

    void
    RoutingTable::printRoutingTable()
    {
        cout<<"---------------Routing Table------------------"<<endl;
        for(std::list<RoutingTableEntry>::iterator it=rTable.begin() ;
                it != rTable.end(); ++it)
        {
            cout<<(*it)<<endl;
        }
    }


//function related to manipulation of dry routing table
    void
    RoutingTable::addNextHopToDryTable(string destRouter, NextHop& nh)
    {
        std::list<RoutingTableEntry >::iterator it = std::find_if( dryTable.begin(),
                dryTable.end(),
                bind(&routingTableEntryCompare, _1, destRouter));
        if ( it == dryTable.end() )
        {
            RoutingTableEntry rte(destRouter);
            rte.getNhl().addNextHop(nh);
            dryTable.push_back(rte);
        }
        else
        {
            (*it).getNhl().addNextHop(nh);
        }
    }

    void
    RoutingTable::printDryRoutingTable()
    {
        cout<<"--------Dry Run's Routing Table--------------"<<endl;
        for(std::list<RoutingTableEntry>::iterator it=dryTable.begin() ;
                it != dryTable.end(); ++it)
        {
            cout<<(*it)<<endl;
        }
    }


    void
    RoutingTable::clearRoutingTable()
    {
        if( rTable.size() > 0 )
        {
            rTable.clear();
        }
    }

    void
    RoutingTable::clearDryRoutingTable()
    {
        if (dryTable.size()>0 )
        {
            dryTable.clear();
        }
    }

}//namespace nlsr

