#include "nrlolsrApp.h"

NrlolsrApp::NrlolsrApp() : nrlolsrObject(GetSocketNotifier(),GetTimerMgr())
{
}

bool 
NrlolsrApp::OnStartup(int argc, const char*const* argv)
{
  DMSG(0,"Enter: NrlolsrApp::OnStartup(argc,argv)\n");
  routingTable=ProtoRouteMgr::Create(); 
  if(routingTable){
    if(!routingTable->Open()){
      DMSG(0,"NrlolsrApp::OnStartup: Error Opening routing table\n");
      return false;
    }
  } else {
    DMSG(0,"NrlolsrApp::OnStartup: Error creating routing table\n");
    return false;
  }
  nrlolsrObject.SetOlsrRouteTable(routingTable);
  if(ProcessCommands(argc,argv)){
    nrlolsrObject.Start();
  } else {
    DMSG(0,"Error parsing commands in NrlolsrApp::OnStartup()\n");
    return false;
  }
  return true;
}

bool 
NrlolsrApp::ProcessCommands(int argc, const char*const* argv)
{
  //DMSG(6,"Enter: NrlolsrApp::ProcessCommands(argc,argv)\n");
  bool printusage = false;
  char localinterfacename[256];
  for(int i=1;i<argc;i++){
    if(!strcmp(argv[i],"-b")){
      i++;
      if(!nrlolsrObject.SetOlsrBroadcastAddress(argv[i],argv[i+1])){
	DMSG(0,"NrlolsrApp: Error setting broadcast address to:\n          Address: %s netmask %s\n",argv[i],argv[i+1]);
	printusage = true;
      }
      i+=1;
    }
    else if(!strcmp(argv[i],"-ipv6")){
      nrlolsrObject.SetOlsrIPv4(false);
    }
    else if(!strcmp(argv[i],"-ipv4")){
      nrlolsrObject.SetOlsrIPv4(true);
    }
    else if(!strcmp(argv[i],"-i")){
      i++;
      strcpy(localinterfacename,argv[i]);
      if(!nrlolsrObject.SetOlsrInterfaceAddress(localinterfacename)){
	DMSG(0,"error setting InterfaceAddress to %s\n",localinterfacename);
	printusage = true;
      }
    } 
    else if(!strcmp(argv[i],"-d")){
      i++;
      if(!nrlolsrObject.SetOlsrDebugLevel(atoi(argv[i]))){
	DMSG(0,"NrlolsrApp: Error setting debug level to %d\n",atoi(argv[i]));
	printusage = true;
      }
    }
    else if(!strcmp(argv[i],"-l")){
      i++;
      if(!nrlolsrObject.SetOlsrDebugLog(argv[i])){
	DMSG(0,"NrlolsrApp: Error opening log file %s\n",argv[i]);
	printusage = true;
      }
    }
    else if(!strcmp(argv[i],"-hi")){
      i++;
      if(!nrlolsrObject.SetOlsrHelloInterval(atof(argv[i]))){
	DMSG(0,"NrlolsrApp: Error setting Hello Interval to %s\n",argv[i]);
	printusage = true;
      }
    }
    else if(!strcmp(argv[i],"-hj")){
      i++;
      if(!nrlolsrObject.SetOlsrHelloJitter(atof(argv[i]))){
	DMSG(0,"NrlolsrApp: Error setting Hello Jitter to %s\n",argv[i]);
	printusage = true;
      }
    }
    else if(!strcmp(argv[i],"-ht")){
      i++;
      if(!nrlolsrObject.SetOlsrHelloTimeout(atof(argv[i]))){
	DMSG(0,"NrlolsrApp: Error setting Hello Timeout factor to %s\n",argv[i]);
	printusage = true;
      }
    }
    else if(!strcmp(argv[i],"-tci")){
      i++;
      if(!nrlolsrObject.SetOlsrTCInterval(atof(argv[i]))){
	DMSG(0,"NrlolsrApp: Error setting TC Interval to %s\n",argv[i]);
	printusage = true;
      }
    }
    else if(!strcmp(argv[i],"-tcj")){
      i++;
      if(!nrlolsrObject.SetOlsrTCJitter(atof(argv[i]))){
	DMSG(0,"NrlolsrApp: Error setting TC Jitter to %s\n",argv[i]);
	printusage = true;
      }
    }
    else if(!strcmp(argv[i],"-tct")){
      i++;
      if(!nrlolsrObject.SetOlsrTCTimeout(atof(argv[i]))){
	DMSG(0,"NrlolsrApp: Error setting TC Timeout factor to %s\n",argv[i]);
	printusage = true;
      }
    }
    else if(!strcmp(argv[i],"-hnai")){
      i++;
      if(!nrlolsrObject.SetOlsrHNAInterval(atof(argv[i]))){
	DMSG(0,"NrlolsrApp: Error setting HNA Interval to %s\n",argv[i]);
	printusage = true;
      }
    }
    else if(!strcmp(argv[i],"-hnaj")){
      i++;
      if(!nrlolsrObject.SetOlsrHNAJitter(atof(argv[i]))){
	DMSG(0,"NrlolsrApp: Error setting HNA Jitter to %s\n",argv[i]);
	printusage = true;
      }
    }
    else if(!strcmp(argv[i],"-hnat")){
      i++;
      if(!nrlolsrObject.SetOlsrHNATimeout(atof(argv[i]))){
	DMSG(0,"NrlolsrApp: Error setting HNA Timeout factor to %s\n",argv[i]);
	printusage = true;
      }
    }
    else if(!strcmp(argv[i],"-al")){
      if(!nrlolsrObject.SetOlsrAllLinks(true)){
	DMSG(0,"NrlolsrApp: odd Error please send command line text to jdean@itd.nrl.navy.mil\n");
	printusage = true;
      }
    }
    else if(!strcmp(argv[i],"-w")){
      i++;
      if(!nrlolsrObject.SetOlsrWillingness(atoi(argv[i]))){
	DMSG(0,"NrlolsrApp: Error setting willingness value to %s\n",argv[i]);
	printusage = true;
      }
    }
    else if(!strcmp(argv[i],"-hys")){
      int j;
      i++;
      if(!strcmp(argv[i],"up")){
	if(!nrlolsrObject.SetOlsrHysUp(atof(argv[i+1]))){
	  DMSG(0,"NrlolsrApp: Error %s is invalid -hys up value\n",argv[i+1]);
	  printusage = true;
	}
	j=i+1;
      } 
      else if (!strcmp(argv[i],"down")){
      	if(!nrlolsrObject.SetOlsrHysDown(atof(argv[i+1]))){
	  DMSG(0,"NrlolsrApp: Error %s is invalid -hys down value\n",argv[i+1]);
	  printusage = true;
	}
	j=i+1;
      } 
      else if (!strcmp(argv[i],"alpha")){
	if(!nrlolsrObject.SetOlsrHysAlpha(atof(argv[i+1]))){
	  DMSG(0,"NrlolsrApp: Error %s is invalid -hys alpha value\n",argv[i+1]);
	  printusage = true;
	}
	j=i+1;
      }
      else if (!strcmp(argv[i],"off")){
	if(!nrlolsrObject.SetOlsrHysOff(true)){
	  DMSG(0,"NrlolsrApp: Error that shouldn't ever happen email jdean@itd.nrl.navy.mil with command line\n");
	  printusage = true;
	}
	j=i;
      }
      else if (!strcmp(argv[i],"on")){
	if(!nrlolsrObject.SetOlsrHysOff(false)){
	  DMSG(0,"NrlolsrApp: Error that shouldn't ever happen email jdean@itd.nrl.navy.mil with command line\n");
	  printusage = true;
	}
	j=i;
      }
      else {
	DMSG(0,"NrlolsrApp: Error %s is invalid -hys option\n",argv[i]);
	printusage = true;
	j=i;
      }
      i=j;
    } 
    else if(!strcmp(argv[i],"-hna")){
      i++;
      if(!strcmp(argv[i],"auto")){
	if(!nrlolsrObject.SetOlsrHNAOff(false)){
	  DMSG(0,"NrlolsrApp: Error that should never happen email jdean@itd.nrl.navy.mil with command line\n");
	  printusage = true;
	}
      } 
      else if(!strcmp(argv[i],"off")){
	if(!nrlolsrObject.SetOlsrHNAOff(true)){
	  DMSG(0,"NrlolsrApp: Error that should never happen email jdean@itd.nrl.navy.mil with command line\n");
	  printusage = true;
	}
      }
      else {
	if(!nrlolsrObject.SetOlsrHNAFile(argv[i])){
	  DMSG(0,"NrlolsrApp: Error opening %s for -hna option\n",argv[i]);
	  printusage = true;
	}
      }
    }
    else if(!strcmp(argv[i],"-qos")){
      i++;
      if(!nrlolsrObject.SetOlsrQos(argv[i])){
	DMSG(0,"NrlolsrApp: Error setting qos to value of %s\n",argv[i]);
	printusage = true;
      }
    }
    else if(!strcmp(argv[i],"-v")){	
      DMSG(0,"NrlolsrApp::version 7.1\n");
      //DMSG(6,"Exit: NrlolsrApp::ProcessCommands(argc,argv)\n");
      return false;
    }
    else {
      printusage = true;
      if(strcmp(argv[i],"-h")){
	DMSG(0,"%s is invalid option\n",argv[i]);
      }
    }
  }
  if(printusage){
    DMSG(0,"NrlolsrApp:options [-i <interfacename>][-d <debuglvl>][-l <debuglogfile>][-al][-h][-v]\n");
    DMSG(0,"                 [-w <willingness>][-hna auto|<filename>|off][-b <broadaddr> <masklength>]\n");
    DMSG(0,"                 [-hi <HelloInterval>][-hj <HelloJitter>][-ht <HelloTimeoutfactor>]\n");
    DMSG(0,"                 [-tci <TCInterval>][-tcj <TCJitter>][-tct <TCTimeoutfactor>][-ipv6][-ipv4]\n");
    DMSG(0,"                 [-hnai <HNAInterval>][-hnaj <HNAJitter>][-hnat <HNATimeoutfactor>]\n");
    DMSG(0,"                 [-hys up <upvalue> | down <downvalue> | alpha <alphavalue> | on | off]\n");
    DMSG(0,"                 [-qos <qosvalue>]\n\n");
    DMSG(0,"see readme.help for more info\n");
    //DMSG(6,"Exit: NrlolsrApp::ProcessCommands(argc,argv)\n");
    return false;
  }
  //DMSG(6,"Exit: NrlolsrApp::ProcessCommands(argc,argv)\n");
  return true;
}
void 
NrlolsrApp::OnShutdown()
{
  nrlolsrObject.Stop();
  routingTable->Close();
  delete routingTable;
  routingTable=NULL;
  return;
}

//void
//NrlolsrApp::recv(Packet *p,Handler *)
//{
//  //check packets with port 689 and to socket recv of nrlolsrObject
//  //check destination with routingTable for next hop and send out to next hop
//  return;
//}

PROTO_INSTANTIATE_APP(NrlolsrApp)

