#include<iostream>
#include<cstdlib>



#include "nlsr.hpp"
#include "nlsr_im.hpp"
#include "nlsr_dm.hpp"
#include "nlsr_tokenizer.hpp"
#include "nlsr_lsdb.hpp"

namespace nlsr
{

    using namespace std;
    using namespace ndn;

    void
    interestManager::processInterest( Nlsr& pnlsr,
                                      const ndn::Name &name,
                                      const ndn::Interest &interest)
    {
        cout << "<< I: " << interest << endl;
        string intName=interest.getName().toUri();
        cout << "Interest Received for Name: "<< intName <<endl;
        nlsrTokenizer nt(intName,"/");
        string chkString("info");
        if( nt.doesTokenExist(chkString) )
        {
            string nbr=nt.getTokenString(nt.getTokenPosition(chkString)+1);
            cout <<"Neighbor: " << nbr <<endl;
            processInterestInfo(pnlsr,nbr,interest);
        }
        //Data data(ndn::Name(interest->getName()).append("testApp").appendVersion());
        //data.setFreshnessPeriod(1000); // 10 sec
        //data.setContent((const uint8_t*)"HELLO KITTY", sizeof("HELLO KITTY"));
        //pnlsr.getKeyChain().sign(data);
        //cout << ">> D: " << data << endl;
        //pnlsr.getNlsrFace().put(data);
    }

    void
    interestManager::processInterestInfo(Nlsr& pnlsr, string& neighbor,
                                         const ndn::Interest &interest)
    {
        if ( pnlsr.getAdl().isNeighbor(neighbor) )
        {
            Data data(ndn::Name(interest.getName()).appendVersion());
            data.setFreshnessPeriod(1000); // 10 sec
            data.setContent((const uint8_t*)"info", sizeof("info"));
            pnlsr.getKeyChain().sign(data);
            cout << ">> D: " << data << endl;
            pnlsr.getNlsrFace().put(data);
            int status=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
            if ( status == 0 )
            {
                string intName=neighbor +"/"+"info"+
                               pnlsr.getConfParameter().getRouterPrefix();
                expressInterest(	pnlsr,intName,2,
                                    pnlsr.getConfParameter().getInterestResendTime());
            }
        }
    }

    void
    interestManager::processInterestTimedOut(Nlsr& pnlsr,
            const ndn::Interest &interest)
    {
        cout << "Timed out interest : " << interest.getName().toUri() << endl;
        string intName=	interest.getName().toUri();
        nlsrTokenizer nt(intName,"/");
        string chkString("info");
        if( nt.doesTokenExist(chkString) )
        {
            string nbr="/" + nt.getFirstToken()
                       +nt.getTokenString(0,nt.getTokenPosition(chkString)-1);
            processInterestTimedOutInfo( pnlsr , nbr , interest);
        }
    }

    void
    interestManager::processInterestTimedOutInfo(Nlsr& pnlsr, string& neighbor,
            const ndn::Interest &interest)
    {
        pnlsr.getAdl().incrementTimedOutInterestCount(neighbor);
        int status=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
        int infoIntTimedOutCount=pnlsr.getAdl().getTimedOutInterestCount(neighbor);
        cout<<"Neighbor: "<< neighbor << endl;
        cout<<"Status: "<< status << endl;
        cout<<"Info Interest Timed out: "<< infoIntTimedOutCount <<endl;
        if((infoIntTimedOutCount < pnlsr.getConfParameter().getInterestRetryNumber()))
        {
            string intName=neighbor +"/"+"info"+
                           pnlsr.getConfParameter().getRouterPrefix();
            expressInterest(	pnlsr,intName,2,
                                pnlsr.getConfParameter().getInterestResendTime());
        }
        else if ( (status == 1) &&
                  (infoIntTimedOutCount == pnlsr.getConfParameter().getInterestRetryNumber()))
        {
            pnlsr.getAdl().setStatusOfNeighbor(neighbor,0);
            pnlsr.incrementAdjBuildCount();
            if ( pnlsr.getIsBuildAdjLsaSheduled() == 0 )
            {
                pnlsr.setIsBuildAdjLsaSheduled(1);
                // event here
                pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(5),
                                                   ndn::bind(&Lsdb::scheduledAdjLsaBuild,pnlsr.getLsdb(),
                                                           boost::ref(pnlsr)));
            }
        }
    }

    void
    interestManager::expressInterest(Nlsr& pnlsr,const string& interestNamePrefix,
                                     int scope, int seconds)
    {
        Interest i((ndn::Name(interestNamePrefix)));
        //i.setScope(scope);
        i.setInterestLifetime(seconds*1000);
        i.setMustBeFresh(true);
        pnlsr.getNlsrFace().expressInterest(i,
                                            ndn::func_lib::bind(&DataManager::processContent,
                                                    &pnlsr.getDm(), boost::ref(pnlsr),_1, _2),
                                            ndn::func_lib::bind(&interestManager::processInterestTimedOut,
                                                    this,boost::ref(pnlsr),_1));
    }


    void
    interestManager::sendScheduledInfoInterest(Nlsr& pnlsr, int seconds)
    {
        std::list<Adjacent> adjList=pnlsr.getAdl().getAdjList();
        for(std::list<Adjacent>::iterator it=adjList.begin(); it!=adjList.end(); ++it)
        {
            string adjName=(*it).getAdjacentName()+"/"+"info"+
                           pnlsr.getConfParameter().getRouterPrefix();
            expressInterest(	pnlsr,adjName,2,
                                pnlsr.getConfParameter().getInterestResendTime());
        }
        scheduleInfoInterest(pnlsr, pnlsr.getConfParameter().getInfoInterestInterval());
    }

    void
    interestManager::scheduleInfoInterest(Nlsr& pnlsr, int seconds)
    {
        EventId eid=pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(seconds),
                    ndn::bind(&interestManager::sendScheduledInfoInterest, this,
                              boost::ref(pnlsr),seconds));
    }


} //namespace nlsr
