#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() == "log-dir"))
    {
      processConfCommandLogDir(pnlsr,nt.getRestOfLine());
    }
    else if( (nt.getFirstToken() == "cert-dir"))
    {
      processConfCommandCertDir(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::processConfCommandCertDir(Nlsr& pnlsr, string command)
  {
    if(command.empty() )
    {
      cerr <<" Wrong command format ! [cert-dir /path/to/cert/dir]!"<<endl;
    }
    else
    {
      pnlsr.getConfParameter().setCertDir(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

