#include<iostream>
#include<fstream>
#include<string>
#include<cstdlib>
#include <sstream>

#include "nlsr_conf_processor.hpp"
#include "nlsr_conf_param.hpp"
#include "utility/nlsr_tokenizer.hpp"
#include "nlsr_adjacent.hpp"


namespace nlsr
{

    using namespace std;

    int
    ConfFileProcessor::processConfFile(Nlsr& pnlsr)
    {
        int ret=0;
        if ( !confFileName.empty())
        {
            std::ifstream inputFile(confFileName.c_str());
            if ( inputFile.is_open())
            {
                for( string line; getline( inputFile, line ); )
                {
                    if (!line.empty() )
                    {
                        if(line[0]!= '#' && line[0]!='!')
                        {
                            ret=processConfCommand(pnlsr, line);
                            if( ret == -1 )
                            {
                                break;
                            }
                        }
                    }
                }
            }
            else
            {
                std::cerr <<"Configuration file: ("<<confFileName<<") does not exist :(";
                std::cerr <<endl;
                ret=-1;
            }
        }
        return ret;
    }


    int
    ConfFileProcessor::processConfCommand(Nlsr& pnlsr, string command)
    {
        int ret=0;
        nlsrTokenizer nt(command," ");
        if( (nt.getFirstToken() == "network"))
        {
            ret=processConfCommandNetwork(pnlsr,nt.getRestOfLine());
        }
        else if( (nt.getFirstToken() == "site-name"))
        {
            ret=processConfCommandSiteName(pnlsr,nt.getRestOfLine());
        }
        else if ( (nt.getFirstToken() == "root-key-prefix"))
        {
            ret=processConfCommandRootKeyPrefix(pnlsr,nt.getRestOfLine());
        }
        else if ( (nt.getFirstToken() == "router-name"))
        {
            ret=processConfCommandRouterName(pnlsr,nt.getRestOfLine());
        }
        else if( (nt.getFirstToken() == "ndnneighbor") )
        {
            ret=processConfCommandNdnNeighbor(pnlsr, nt.getRestOfLine());
        }
        else if( (nt.getFirstToken() == "link-cost"))
        {
            ret=processConfCommandLinkCost(pnlsr, nt.getRestOfLine());
        }
        else if( (nt.getFirstToken() == "ndnname") )
        {
            ret=processConfCommandNdnName(pnlsr, nt.getRestOfLine());
        }
        else if( (nt.getFirstToken() == "interest-retry-num"))
        {
            processConfCommandInterestRetryNumber(pnlsr,nt.getRestOfLine());
        }
        else if( (nt.getFirstToken() == "interest-resend-time"))
        {
            processConfCommandInterestResendTime(pnlsr,nt.getRestOfLine());
        }
        else if( (nt.getFirstToken() == "lsa-refresh-time"))
        {
            processConfCommandLsaRefreshTime(pnlsr,nt.getRestOfLine());
        }
        else if( (nt.getFirstToken() == "max-faces-per-prefix"))
        {
            processConfCommandMaxFacesPerPrefix(pnlsr,nt.getRestOfLine());
        }
        else if( (nt.getFirstToken() == "logdir"))
        {
            processConfCommandLogDir(pnlsr,nt.getRestOfLine());
        }
        else if( (nt.getFirstToken() == "detailed-logging") )
        {
            processConfCommandDetailedLogging(pnlsr,nt.getRestOfLine());
        }
        else if( (nt.getFirstToken() == "debugging") )
        {
            processConfCommandDebugging(pnlsr,nt.getRestOfLine());
        }
        else if( (nt.getFirstToken() == "chronosync-sync-prefix") )
        {
            processConfCommandChronosyncSyncPrefix(pnlsr,nt.getRestOfLine());
        }
        else if( (nt.getFirstToken() == "hyperbolic-cordinate") )
        {
            processConfCommandHyperbolicCordinate(pnlsr,nt.getRestOfLine());
        }
        else if( (nt.getFirstToken() == "hyperbolic-routing"))
        {
            processConfCommandIsHyperbolicCalc(pnlsr,nt.getRestOfLine());
        }
        else if( (nt.getFirstToken() == "tunnel-type"))
        {
            processConfCommandTunnelType(pnlsr,nt.getRestOfLine());
        }
        else
        {
            cout << "Wrong configuration Command: "<< nt.getFirstToken()<<endl;
        }
        return ret;
    }

    int
    ConfFileProcessor::processConfCommandNetwork(Nlsr& pnlsr, string command)
    {
        if(command.empty() )
        {
            cerr <<" Network can not be null or empty :( !"<<endl;
            return -1;
        }
        else
        {
            if(command[command.size()-1] == '/' )
            {
                command.erase(command.size() - 1);
            }
            if(command[0] == '/' )
            {
                command.erase(0,1);
            }
            pnlsr.getConfParameter().setNetwork(command);
        }
        return 0;
    }

    int
    ConfFileProcessor::processConfCommandSiteName(Nlsr& pnlsr, string command)
    {
        if(command.empty() )
        {
            cerr <<"Site name can not be null or empty :( !"<<endl;
            return -1;
        }
        else
        {
            if(command[command.size()-1] == '/' )
            {
                command.erase(command.size() - 1);
            }
            if(command[0] == '/' )
            {
                command.erase(0,1);
            }
            pnlsr.getConfParameter().setSiteName(command);
        }
        return 0;
    }

    int
    ConfFileProcessor::processConfCommandRootKeyPrefix(Nlsr& pnlsr, string command)
    {
        if(command.empty() )
        {
            cerr <<"Root Key Prefix can not be null or empty :( !"<<endl;
            return -1;
        }
        else
        {
            if(command[command.size()-1] == '/' )
            {
                command.erase(command.size() - 1);
            }
            if(command[0] == '/' )
            {
                command.erase(0,1);
            }
            pnlsr.getConfParameter().setRootKeyPrefix(command);
        }
        return 0;
    }


    int
    ConfFileProcessor::processConfCommandRouterName(Nlsr& pnlsr, string command)
    {
        if(command.empty() )
        {
            cerr <<" Router name can not be null or empty :( !"<<endl;
            return -1;
        }
        else
        {
            if(command[command.size()-1] == '/' )
            {
                command.erase(command.size() - 1);
            }
            if(command[0] == '/' )
            {
                command.erase(0,1);
            }
            pnlsr.getConfParameter().setRouterName(command);
        }
        return 0;
    }

    int
    ConfFileProcessor::processConfCommandInterestRetryNumber(Nlsr& pnlsr,
            string command)
    {
        if(command.empty() )
        {
            cerr <<" Wrong command format ! [interest-retry-num n]"<<endl;
        }
        else
        {
            int irn;
            stringstream ss(command.c_str());
            ss>>irn;
            if ( irn >=1 && irn <=5)
            {
                pnlsr.getConfParameter().setInterestRetryNumber(irn);
            }
        }
        return 0;
    }

    int
    ConfFileProcessor::processConfCommandInterestResendTime(Nlsr& pnlsr,
            string command)
    {
        if(command.empty() )
        {
            cerr <<" Wrong command format ! [interest-resend-time s]"<<endl;
        }
        else
        {
            int irt;
            stringstream ss(command.c_str());
            ss>>irt;
            if( irt>=1 && irt <=20)
            {
                pnlsr.getConfParameter().setInterestResendTime(irt);
            }
        }
        return 0;
    }

    int
    ConfFileProcessor::processConfCommandLsaRefreshTime(Nlsr& pnlsr, string command)
    {
        if(command.empty() )
        {
            cerr <<" Wrong command format ! [interest-resend-time s]"<<endl;
        }
        else
        {
            int lrt;
            stringstream ss(command.c_str());
            ss>>lrt;
            if ( lrt>= 240 && lrt<=7200)
            {
                pnlsr.getConfParameter().setLsaRefreshTime(lrt);
            }
        }
        return 0;
    }

    int
    ConfFileProcessor::processConfCommandMaxFacesPerPrefix(Nlsr& pnlsr,
            string command)
    {
        if(command.empty() )
        {
            cerr <<" Wrong command format ! [max-faces-per-prefix n]"<<endl;
        }
        else
        {
            int mfpp;
            stringstream ss(command.c_str());
            ss>>mfpp;
            if ( mfpp>=0 && mfpp<=60)
            {
                pnlsr.getConfParameter().setMaxFacesPerPrefix(mfpp);
            }
        }
        return 0;
    }

    int
    ConfFileProcessor::processConfCommandTunnelType(Nlsr& pnlsr, string command)
    {
        if(command.empty() )
        {
            cerr <<" Wrong command format ! [tunnel-type tcp/udp]!"<<endl;
        }
        else
        {
            if(command == "tcp" || command == "TCP" )
            {
                pnlsr.getConfParameter().setTunnelType(1);
            }
            else if(command == "udp" || command == "UDP")
            {
                pnlsr.getConfParameter().setTunnelType(0);
            }
            else
            {
                cerr <<" Wrong command format ! [tunnel-type tcp/udp]!"<<endl;
            }
        }
        return 0;
    }

    int
    ConfFileProcessor::processConfCommandChronosyncSyncPrefix(Nlsr& pnlsr,
            string command)
    {
        if(command.empty() )
        {
            cerr <<" Wrong command format ! [chronosync-sync-prefix name/prefix]!"<<endl;
        }
        else
        {
            pnlsr.getConfParameter().setChronosyncSyncPrefix(command);
        }
        return 0;
    }


    int
    ConfFileProcessor::processConfCommandLogDir(Nlsr& pnlsr, string command)
    {
        if(command.empty() )
        {
            cerr <<" Wrong command format ! [log-dir /path/to/log/dir]!"<<endl;
        }
        else
        {
            pnlsr.getConfParameter().setLogDir(command);
        }
        return 0;
    }

    int
    ConfFileProcessor::processConfCommandDebugging(Nlsr& pnlsr, string command)
    {
        if(command.empty() )
        {
            cerr <<" Wrong command format ! [debugging on/of]!"<<endl;
        }
        else
        {
            if(command == "on" || command == "ON" )
            {
                pnlsr.getConfParameter().setDebugging(1);
            }
            else if(command == "off" || command == "off")
            {
                pnlsr.getConfParameter().setDebugging(0);
            }
            else
            {
                cerr <<" Wrong command format ! [debugging on/off]!"<<endl;
            }
        }
        return 0;
    }

    int
    ConfFileProcessor::processConfCommandDetailedLogging(Nlsr& pnlsr,
            string command)
    {
        if(command.empty() )
        {
            cerr <<" Wrong command format ! [detailed-logging on/off]!"<<endl;
        }
        else
        {
            if(command == "on" || command == "ON" )
            {
                pnlsr.getConfParameter().setDetailedLogging(1);
            }
            else if(command == "off" || command == "off")
            {
                pnlsr.getConfParameter().setDetailedLogging(0);
            }
            else
            {
                cerr <<" Wrong command format ! [detailed-logging on/off]!"<<endl;
            }
        }
        return 0;
    }

    int
    ConfFileProcessor::processConfCommandIsHyperbolicCalc(Nlsr& pnlsr,
            string command)
    {
        if(command.empty() )
        {
            cerr <<" Wrong command format ! [hyperbolic-routing on/off/dry-run]!"<<endl;
        }
        else
        {
            if(command == "on" || command == "ON" )
            {
                pnlsr.getConfParameter().setIsHyperbolicCalc(1);
            }
            else if(command == "dry-run" || command == "DRY-RUN")
            {
                pnlsr.getConfParameter().setIsHyperbolicCalc(2);
            }
            else if(command == "off" || command == "off")
            {
                pnlsr.getConfParameter().setIsHyperbolicCalc(0);
            }
            else
            {
                cerr <<" Wrong command format ! [hyperbolic-routing on/off/dry-run]!"<<endl;
            }
        }
        return 0;
    }

    int
    ConfFileProcessor::processConfCommandHyperbolicCordinate(Nlsr& pnlsr,
            string command)
    {
        if(command.empty() )
        {
            cerr <<" Wrong command format ! [hyperbolic-cordinate r 0]!"<<endl;
            if (pnlsr.getConfParameter().getIsHyperbolicCalc() > 0 )
            {
                return -1;
            }
        }
        else
        {
            nlsrTokenizer nt(command," ");
            stringstream ssr(nt.getFirstToken().c_str());
            stringstream sst(nt.getRestOfLine().c_str());
            double r,theta;
            ssr>>r;
            sst>>theta;
            pnlsr.getConfParameter().setCorR(r);
            pnlsr.getConfParameter().setCorTheta(theta);
        }
        return 0;
    }


    int
    ConfFileProcessor::processConfCommandNdnNeighbor(Nlsr& pnlsr, string command)
    {
        if(command.empty() )
        {
            cerr <<" Wrong command format ! [ndnneighbor /nbr/name/ FaceId]!"<<endl;
        }
        else
        {
            nlsrTokenizer nt(command," ");
            if( nt.getRestOfLine().empty())
            {
                cerr <<" Wrong command format ! [ndnneighbor /nbr/name/ FaceId]!"<<endl;
                return 0;
            }
            else
            {
                stringstream sst(nt.getRestOfLine().c_str());
                int faceId;
                sst>>faceId;
                Adjacent adj(nt.getFirstToken(),faceId,0.0,0,0);
                pnlsr.getAdl().insert(adj);
            }
        }
        return 0;
    }

    int
    ConfFileProcessor::processConfCommandNdnName(Nlsr& pnlsr, string command)
    {
        if(command.empty() )
        {
            cerr <<" Wrong command format ! [ndnname name/prefix]!"<<endl;
        }
        else
        {
            pnlsr.getNpl().insertIntoNpl(command);
        }
        return 0;
    }


    int
    ConfFileProcessor::processConfCommandLinkCost(Nlsr& pnlsr, string command)
    {
        if(command.empty() )
        {
            cerr <<" Wrong command format ! [link-cost nbr/name cost]!"<<endl;
            if (pnlsr.getConfParameter().getIsHyperbolicCalc() > 0 )
            {
                return -1;
            }
        }
        else
        {
            nlsrTokenizer nt(command," ");
            stringstream sst(nt.getRestOfLine().c_str());
            double cost;
            sst>>cost;
            pnlsr.getAdl().updateAdjacentLinkCost(nt.getFirstToken(),cost);
        }
        return 0;
    }

} //namespace nlsr

