#include "scmxx_opt.h"
#include <helper.h>
#include <options.h>

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

static struct args_t args;

#include "config.h"
void args_init () {
  args.port.type = TTY_TYPE_SERIAL;
  args.port.device = TTYPORT;
  args.port.baud = TTYSPEED;
  args.port.timeout = 100;
  args.port.ignorebits = 1;
  args.port.startdelay = 0;

  args.myparams.text=NULL;
  args.myparams.number=NULL;
  args.myparams.mem=NULL;
  args.myparams.slot=SCMXX_SLOT_UNDEFINED;

  args.mysmsopts.flash=0;
  args.mysmsopts.srr=0;
  args.mysmsopts.unicode=0;
  args.mysmsopts.direct=0;
  args.mysmsopts.sort_mode="type,time";

  args.scmxx_action=0;
  args.scmxx_ftype=0;

  args.myFILE=NULL;
  args.myPIPE=NULL;

  args.info = 0;
  args.meminfo = 0;
  args.lockinfo = 0;
  args.time = 0;
  args.lock = NULL;
  args.state_change = 0;
  args.smsc = 0;
  args.dial = 0;
  args.hangup = 0;
  args.reset = 0;
  args.help = 0;
  args.version = 0;

  args.verbose = 0;
  args.pin = NULL;
  args.system_charset = NULL;
}

static void arg_fill_slot (char* argument) {
  if (is_number(argument)) {
    args.myparams.slot = atoi(argument);
  } else {
    if(!strcmp(argument,"all")) {
      args.myparams.slot = SCMXX_SLOT_ALL;
    } else if(!strcmp(argument,"sent")) {
      args.myparams.slot = SCMXX_SLOT_SMS_SENT;
    } else if(!strcmp(argument,"unsent")) {
      args.myparams.slot = SCMXX_SLOT_SMS_UNSENT;
    } else if(!strcmp(argument,"read")) {
      args.myparams.slot = SCMXX_SLOT_SMS_READ;
    } else if(!strcmp(argument,"unread")) {
      args.myparams.slot = SCMXX_SLOT_SMS_UNREAD;
    } else if (!strcmp(argument,"last")) {
      args.myparams.slot = SCMXX_SLOT_LAST;
    } else {
      args.myparams.slot = SCMXX_SLOT_UNDEFINED;
    }
  }
}

static void arg_fill (int short_opt,
		      const char* long_opt,
		      char* argument)
{
  int temp;

  switch (short_opt) {
  case 'b': //--baud
    args.port.baud = argument;
    break;
  case 'd': //--device
    args.port.device = str_dup(argument);
    break;
  case 'g':
    args.scmxx_action |= SCMXX_ACTION_GET;
    break;
  case 'h':
    args.help=1;
    break;
  case 'i':
    args.info=1;
    break;
  case 'l':
    arg_fill_slot(argument);
    break;
  case 'm':
    args.myparams.mem = str_dup(argument);
    break;
  case 'n':
    if (str_len(argument)) args.myparams.number=str_dup(argument);
    break;
  case 'o':
    args.myFILE=str_dup(argument);
    break;
  case 'p':
    args.myPIPE=str_dup(argument);
    break;
  case 'q':
    args.verbose--;
    break;
  case 'r':
    args.scmxx_action |= SCMXX_ACTION_REMOVE;
    break;
  case 's': 
    args.scmxx_action |= SCMXX_ACTION_SEND;
    break;
  case 't':
    if (str_len(argument)) args.myparams.text=str_dup(argument);
    break;
  case 'v':
    args.verbose++;
    break;
  case 'N':
    args.scmxx_ftype = SCMXX_FTYPE_BINARY;
    break;
  case 'P':
    args.scmxx_ftype = SCMXX_FTYPE_PBOOK;
    break;
  case 'S':
    args.scmxx_ftype = SCMXX_FTYPE_SMS;
    break;
  case 'V':
    args.version=1;
    break;
  case 0:
    if (str_len(long_opt)) {
      if (!strcmp(long_opt,"pin")) {
	args.pin = str_dup(argument);
      } else if (!strcmp(long_opt,"unicode")) {
	args.mysmsopts.unicode=1;
      } else if (!strcmp(long_opt,"direct")) {
	args.mysmsopts.direct=1;
      } else if (!strcmp(long_opt,"srr")) {
	args.mysmsopts.srr=1;
      } else if (!strcmp(long_opt,"flash")) {
	args.mysmsopts.flash=1;
      } else if (!strcmp(long_opt,"ignore-serial-bits")) {
	args.port.ignorebits=1;
      } else if (!strcmp(long_opt,"keep-serial-bits")) {
	args.port.ignorebits=0;
      } else if (!strcmp(long_opt,"device-timeout")) {
	if (argument) {
	  temp = atoi(argument);
	  if (temp < 1) {
	    args.port.timeout = 10;
	  } else if (1 <= temp && temp <= 25) {
	    args.port.timeout = 10*temp;
	  } else if (temp > 25) {
	    args.port.timeout = 0;
	  }
	}
      } else if (!strcmp(long_opt,"start-delay")) {
	args.port.startdelay = atoi(argument);
      } else if (!strcmp(long_opt,"reset")) {
	args.reset=1;
      } else if (!strcmp(long_opt,"set-time")) {
	args.time=1;
      } else if (!strcmp(long_opt,"set-smsc")) {
	args.smsc=1;
      } else if (!strcmp(long_opt,"lock")) {
	args.lock=str_dup(argument);
      } else if (!strcmp(long_opt,"enable")) {
	args.state_change=1;
      } else if (!strcmp(long_opt,"disable")) {
	args.state_change=-1;
      } else if (!strcmp(long_opt,"dial")) {
	args.dial=1;
      } else if (!strcmp(long_opt,"hangup")) {
	args.hangup=1;
      } else if (!strcmp(long_opt,"mem-info")) {
	args.meminfo = 1;
      } else if (!strcmp(long_opt,"lock-info")) {
	args.lockinfo = 1;
      } else if (!strcmp(long_opt,"sort")) { //old, compat
	args.mysmsopts.sort_mode = str_dup(argument);
      } else if (!strcmp(long_opt,"system-charset")) {
	args.system_charset = str_dup(argument);
      }
    }
    break;
  }
}

//gettext workaround
#ifdef _
#undef _
#endif
#define _(s) s
struct args_def_type args_type_list[] = {
  { 0, _("options"), 0 },
  { 1, _("actions"), 1 },
  { 2, _("memory types"), 0 },
  { 3, _("memory type options"), 0 },
  { 4, _("SMS options"), 0 },
  ARGS_DEF_TYPE_LAST
};

struct args_def args_list[] = {
  {"baud",'b',"SCMXX_BAUD",ARGS_PARAM_REQ,_("rate"),0,
   _("specify another than the compiled in baudrate")},
  {"binary",'N',NULL,ARGS_PARAM_NONE,NULL,2,
   _("binary file transfer")},
  {"device",'d',"SCMXX_TTY",ARGS_PARAM_REQ,_("device"),0,
   _("specify another than the compiled in device")},
  {"device-timeout",0,NULL,ARGS_PARAM_REQ,_("seconds"),0,
   _("return after this time if there is no answer")},
  {"dial",0,NULL,ARGS_PARAM_NONE,NULL,1,
   _("dials a number (requires option -n)")}, //since 0.7.4
  {"direct",0,NULL,ARGS_PARAM_NONE,NULL,4,
   _("send/receive without storing in the phone")},
  {"disable",0,NULL,ARGS_PARAM_NONE,NULL,1,
   _("disable e.g. a lock")}, //since 0.8.0
  {"enable",0,NULL,ARGS_PARAM_NONE,NULL,1,
   _("enable e.g. a lock")}, //since 0.8.0
  {"flash",0,NULL,ARGS_PARAM_NONE,NULL,4,
   _("make the sms appear directly (if supported by the receiving entity)")},
  {"get",'g',NULL,ARGS_PARAM_NONE,NULL,1,
   _("get something from the phone")},
  {"hangup",0,NULL,ARGS_PARAM_NONE,NULL,1,
   _("hangup all active calls")}, //since 0.8.0
  {"help",'h',NULL,ARGS_PARAM_NONE,NULL,0,
   _("print this message")},
  {"ignore-serial-bits",0,NULL,ARGS_PARAM_NONE,NULL,0,
   _("do not use current serial port settings as base (default)")},
  {"info",'i',NULL,ARGS_PARAM_NONE,NULL,1,
   _("show various information")},
  {"keep-serial-bits",0,NULL,ARGS_PARAM_NONE,NULL,0,
   _("use current serial port settings as base")},
  {"lock",0,NULL,ARGS_PARAM_REQ,_("lock"),1,
   _("selects a lock to change (might need option --pin)")}, //since 0.8.0
  {"lock-info",0,NULL,ARGS_PARAM_NONE,NULL,1,
   _("show lock information")},
  {"mem",'m',NULL,ARGS_PARAM_REQ,_("mem"),3,
   _("select a memory")},
  {"mem-info",0,NULL,ARGS_PARAM_NONE,NULL,1,
   _("show memory information")},
  {"number",'n',NULL,ARGS_PARAM_REQ,_("number"),0,
   _("specify number on send")},
  {"out",'o',NULL,ARGS_PARAM_REQ,_("file"),0,
   _("specify a file when getting ('-' for stdout)")},
  {"pbook",'P',NULL,ARGS_PARAM_NONE,NULL,2,
   _("phonebook")},
  {"pin",0,NULL,ARGS_PARAM_REQ,"PIN",4,
   _("use this pin if one is needed")},
  {"pipe",'p',NULL,ARGS_PARAM_REQ,_("program"),0,
   _("specify a pipe to use")},
  {"quiet",'q',NULL,ARGS_PARAM_NONE,NULL,0,
   _("decreases verbosity by 1")},
  {"remove",'r',NULL,ARGS_PARAM_NONE,NULL,1,
   _("removes something from the phone")},
  {"reset",0,NULL,ARGS_PARAM_NONE,NULL,1,
   _("sends some special characters")},
  {"send",'s',NULL,ARGS_PARAM_NONE,NULL,1,
   _("sends something to the phone")},
  {"set-smsc",0,NULL,ARGS_PARAM_NONE,NULL,1,
   _("set the SMSC number (requires option -n)")},
  {"set-time",0,NULL,ARGS_PARAM_NONE,NULL,1,
   _("synchronize time on phone")},
  {"slot",'l',NULL,ARGS_PARAM_REQ,_("slot"),3,
   _("select a slot or slot group")},
  {"sms",'S',NULL,ARGS_PARAM_NONE,NULL,2,
   _("short messages")},
  {"sort",0,NULL,ARGS_PARAM_REQ,_("method"),4,
   _("sort short message on getting([type,][slot|time])")}, //since 0.7.3
  {"srr",0,NULL,ARGS_PARAM_NONE,NULL,4,
   _("request a status report from the SMSC")},
  {"start-delay",0,NULL,ARGS_PARAM_REQ,_("seconds"),0,
   _("wait this time after opening device")},
  {"system-charset",0,NULL,ARGS_PARAM_REQ,_("charset"),0,
   _("use charset for input/output from/to system")}, //since 0.7.5
  {"text",'t',NULL,ARGS_PARAM_REQ,_("text"),0,
   _("specify content on send")},
  {"unicode",0,NULL,ARGS_PARAM_NONE,NULL,4,
   _("use UCS-2 (unicode) as charset")},
  {"verbose",'v',NULL,ARGS_PARAM_NONE,NULL,0,
   _("increases verbosity by 1")},
  {"version",'V',NULL,ARGS_PARAM_NONE,NULL,0,
   _("print the version number")},
  ARGS_DEF_LAST
};

void scmxx_use_envvars () {
  use_envvars(args_list,arg_fill);
}

int scmxx_conffile_parse (char* filename) {
  int retval = 0;
  char* filepath = configfile_get_path(PACKAGE_NAME,filename);
  retval = configfile_parse(filepath,args_list,arg_fill);
  mem_realloc(filepath,0);
  return retval;
}

char** scmxx_args_parse (int argc, char** argv) {
  return args_parse(argc,argv,args_list,arg_fill);
}

struct args_t* scmxx_get_args () {
  return &args;
}
