#include<string>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<limits>

#include "nlsr_lsa.hpp"
#include "nlsr_npl.hpp"
#include "nlsr_adjacent.hpp"
#include "nlsr.hpp"

namespace nlsr
{

    using namespace std;


    string
    NameLsa::getNameLsaKey()
    {
        string key;
        key=origRouter + "/" + boost::lexical_cast<std::string>(1);
        return key;
    }

    NameLsa::NameLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt, Npl npl)
    {
        origRouter=origR;
        lsType=lst;
        lsSeqNo=lsn;
        lifeTime=lt;
        std::list<string> nl=npl.getNameList();
        for( std::list<string>::iterator it=nl.begin(); it != nl.end(); it++)
        {
            addNameToLsa((*it));
        }
    }

    string
    NameLsa::getNameLsaData()
    {
        string nameLsaData;
        nameLsaData=origRouter + "|" + boost::lexical_cast<std::string>(lsType) + "|"
                    + boost::lexical_cast<std::string>(lsSeqNo) + "|"
                    + boost::lexical_cast<std::string>(lifeTime);
        nameLsaData+="|";
        nameLsaData+=boost::lexical_cast<std::string>(npl.getNplSize());
        std::list<string> nl=npl.getNameList();
        for( std::list<string>::iterator it=nl.begin(); it != nl.end(); it++)
        {
            nameLsaData+="|";
            nameLsaData+=(*it);
        }
        return nameLsaData;
    }

    std::ostream&
    operator<<(std::ostream& os, NameLsa& nLsa)
    {
        os<<"Name Lsa: "<<endl;
        os<<"  Origination Router: "<<nLsa.getOrigRouter()<<endl;
        os<<"  Ls Type: "<<(unsigned short)nLsa.getLsType()<<endl;
        os<<"  Ls Seq No: "<<(unsigned int)nLsa.getLsSeqNo()<<endl;
        os<<"  Ls Lifetime: "<<(unsigned int)nLsa.getLifeTime()<<endl;
        os<<"  Names: "<<endl;
        int i=1;
        std::list<string> nl=nLsa.getNpl().getNameList();
        for( std::list<string>::iterator it=nl.begin(); it != nl.end(); it++)
        {
            os<<"    Name "<<i<<": "<<(*it)<<endl;
        }
        return os;
    }



    CorLsa::CorLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt
                   , double r, double theta)
    {
        origRouter=origR;
        lsType=lst;
        lsSeqNo=lsn;
        lifeTime=lt;
        corRad=r;
        corTheta=theta;
    }

    string
    CorLsa::getCorLsaKey()
    {
        string key;
        key=origRouter + "/" + boost::lexical_cast<std::string>(3);
        return key;
    }

    bool
    CorLsa::isLsaContentEqual(CorLsa& clsa)
    {
        return (std::abs(corRad - clsa.getCorRadius()) <
                std::numeric_limits<double>::epsilon()) &&
               (std::abs(corTheta - clsa.getCorTheta()) <
                std::numeric_limits<double>::epsilon());
    }

    string
    CorLsa::getCorLsaData()
    {
        string corLsaData;
        corLsaData=origRouter + "|";
        corLsaData+=(boost::lexical_cast<std::string>(lsType) + "|");
        corLsaData+=(boost::lexical_cast<std::string>(lsSeqNo) + "|");
        corLsaData+=(boost::lexical_cast<std::string>(lifeTime) + "|");
        corLsaData+=(boost::lexical_cast<std::string>(corRad) + "|");
        corLsaData+=(boost::lexical_cast<std::string>(corTheta) + "|");
        return corLsaData;
    }

    std::ostream&
    operator<<(std::ostream& os, CorLsa& cLsa)
    {
        os<<"Cor Lsa: "<<endl;
        os<<"  Origination Router: "<<cLsa.getOrigRouter()<<endl;
        os<<"  Ls Type: "<<(unsigned short)cLsa.getLsType()<<endl;
        os<<"  Ls Seq No: "<<(unsigned int)cLsa.getLsSeqNo()<<endl;
        os<<"  Ls Lifetime: "<<(unsigned int)cLsa.getLifeTime()<<endl;
        os<<"    Hyperbolic Radius: "<<cLsa.getCorRadius()<<endl;
        os<<"    Hyperbolic Theta: "<<cLsa.getCorTheta()<<endl;
        return os;
    }


    AdjLsa::AdjLsa(string origR, uint8_t lst, uint32_t lsn, uint32_t lt,
                   uint32_t nl ,Adl padl)
    {
        origRouter=origR;
        lsType=lst;
        lsSeqNo=lsn;
        lifeTime=lt;
        noLink=nl;
        std::list<Adjacent> al=padl.getAdjList();
        for( std::list<Adjacent>::iterator it=al.begin(); it != al.end(); it++)
        {
            if((*it).getStatus()==1)
            {
                addAdjacentToLsa((*it));
            }
        }
    }

    string
    AdjLsa::getAdjLsaKey()
    {
        string key;
        key=origRouter + "/" + boost::lexical_cast<std::string>(2);
        return key;
    }

    bool
    AdjLsa::isLsaContentEqual(AdjLsa& alsa)
    {
        return adl.isAdlEqual(alsa.getAdl());
    }


    string
    AdjLsa::getAdjLsaData()
    {
        string adjLsaData;
        adjLsaData=origRouter + "|" + boost::lexical_cast<std::string>(lsType) + "|"
                   + boost::lexical_cast<std::string>(lsSeqNo) + "|"
                   + boost::lexical_cast<std::string>(lifeTime);
        adjLsaData+="|";
        adjLsaData+=boost::lexical_cast<std::string>(adl.getAdlSize());
        std::list<Adjacent> al=adl.getAdjList();
        for( std::list<Adjacent>::iterator it=al.begin(); it != al.end(); it++)
        {
            adjLsaData+="|";
            adjLsaData+=(*it).getAdjacentName();
            adjLsaData+="|";
            adjLsaData+=boost::lexical_cast<std::string>((*it).getConnectingFace());
            adjLsaData+="|";
            adjLsaData+=boost::lexical_cast<std::string>((*it).getLinkCost());
        }
        return adjLsaData;
    }


    void
    AdjLsa::addNptEntriesForAdjLsa(Nlsr& pnlsr)
    {
        if ( getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
        {
            pnlsr.getNpt().addNpte(getOrigRouter(), getOrigRouter(),pnlsr);
        }
    }


    void
    AdjLsa::removeNptEntriesForAdjLsa(Nlsr& pnlsr)
    {
        if ( getOrigRouter() !=pnlsr.getConfParameter().getRouterPrefix() )
        {
            pnlsr.getNpt().removeNpte(getOrigRouter(), getOrigRouter(),pnlsr);
        }
    }



    std::ostream&
    operator<<(std::ostream& os, AdjLsa& aLsa)
    {
        os<<"Adj Lsa: "<<endl;
        os<<"  Origination Router: "<<aLsa.getOrigRouter()<<endl;
        os<<"  Ls Type: "<<(unsigned short)aLsa.getLsType()<<endl;
        os<<"  Ls Seq No: "<<(unsigned int)aLsa.getLsSeqNo()<<endl;
        os<<"  Ls Lifetime: "<<(unsigned int)aLsa.getLifeTime()<<endl;
        os<<"  No Link: "<<(unsigned int)aLsa.getNoLink()<<endl;
        os<<"  Adjacents: "<<endl;
        int i=1;
        std::list<Adjacent> al=aLsa.getAdl().getAdjList();
        for( std::list<Adjacent>::iterator it=al.begin(); it != al.end(); it++)
        {
            os<<"    Adjacent "<<i<<": "<<endl;
            os<<"      Adjacent Name: "<<(*it).getAdjacentName()<<endl;
            os<<"      Connecting Face: "<<(*it).getConnectingFace()<<endl;
            os<<"      Link Cost: "<<(*it).getLinkCost()<<endl;
        }
        return os;
    }

}//namespace nlsr
