#ifndef CONF_PARAM_HPP
#define CONF_PARAM_HPP

#include<iostream>

namespace nlsr
{

    using namespace std;

    class ConfParameter
    {

    public:
        ConfParameter()
            :chronosyncSyncPrefix("ndn/nlsr/sync")
            ,chronosyncLsaPrefix("/ndn/nlsr/LSA")
        {
            isStrictHierchicalKeyCheck=0;
            interestRetryNumber=3;
            interestResendTime=5;
            infoInterestInterval=60;
            lsaRefreshTime=1800;
            routerDeadInterval=3600;
            maxFacesPerPrefix=0;
            tunnelType=0;
            detailedLogging=0;
            debugging=0;
            isHyperbolicCalc=0;
        }

        void setRouterName(const string& rn)
        {
            routerName=rn;
        }

        string getRouterName()
        {
            return routerName;
        }

        void setSiteName(const string& sn)
        {
            siteName=sn;
        }

        string getSiteName()
        {
            return siteName;
        }

        void setNetwork(const string& nn)
        {
            network=nn;
        }

        string getNetwork()
        {
            return network;
        }

        void buildRouterPrefix()
        {
            routerPrefix="/"+network+"/"+siteName+"/"+routerName;
        }

        string getRouterPrefix()
        {
            return routerPrefix;
        }

        void setInterestRetryNumber(int irn)
        {
            interestRetryNumber=irn;
        }

        int getInterestRetryNumber()
        {
            return interestRetryNumber;
        }

        void setInterestResendTime(int irt)
        {
            interestResendTime=irt;
        }

        int getInterestResendTime()
        {
            return interestResendTime;
        }

        void setLsaRefreshTime(int lrt)
        {
            lsaRefreshTime=lrt;
            routerDeadInterval=2*lsaRefreshTime;
        }

        int getLsaRefreshTime()
        {
            return lsaRefreshTime;
        }

        void setRouterDeadInterval(int rdt)
        {
            routerDeadInterval=rdt;
        }

        long int getRouterDeadInterval()
        {
            return routerDeadInterval;
        }

        void setMaxFacesPerPrefix(int mfpp)
        {
            maxFacesPerPrefix=mfpp;
        }

        int getMaxFacesPerPrefix()
        {
            return maxFacesPerPrefix;
        }

        void setLogDir(string ld)
        {
            logDir=ld;
        }

        string getLogDir()
        {
            return logDir;
        }

        void setDetailedLogging(int dl)
        {
            detailedLogging=dl;
        }

        int getDetailedLogging()
        {
            return detailedLogging;
        }

        void setDebugging(int d)
        {
            debugging=d;
        }

        int getDebugging()
        {
            return debugging;
        }

        void setIsHyperbolicCalc(int ihc)
        {
            isHyperbolicCalc=ihc;
        }

        int getIsHyperbolicCalc()
        {
            return isHyperbolicCalc;
        }

        void setCorR(double cr)
        {
            corR=cr;
        }

        double getCorR()
        {
            return corR;
        }

        void setCorTheta(double ct)
        {
            corTheta=ct;
        }

        double getCorTheta()
        {
            return corTheta;
        }

        void setTunnelType(int tt)
        {
            tunnelType=tt;
        }

        int getTunnelType()
        {
            return tunnelType;
        }

        void setChronosyncSyncPrefix(const string& csp)
        {
            chronosyncSyncPrefix=csp;
        }

        string getChronosyncSyncPrefix()
        {
            return chronosyncSyncPrefix;
        }

        int getInfoInterestInterval()
        {
            return infoInterestInterval;
        }

        void setInfoInterestInterval(int iii)
        {
            infoInterestInterval=iii;
        }

    private:
        string routerName;
        string siteName;
        string network;

        string routerPrefix;
        string lsaRouterPrefix;

        string chronosyncSyncPrefix;
        string chronosyncLsaPrefix;

        int interestRetryNumber;
        int interestResendTime;
        int infoInterestInterval;
        int lsaRefreshTime;
        int routerDeadInterval;

        int maxFacesPerPrefix;
        string logDir;
        string logFile;
        int detailedLogging;
        int debugging;

        int isHyperbolicCalc;
        double corR;
        double corTheta;

        int tunnelType;
        int isStrictHierchicalKeyCheck;

    };

    std::ostream&
    operator << (std::ostream &os, ConfParameter &cfp);

} // namespace nlsr

#endif
