/*
   <p>Test harness for the adjustdate package.</p>

               Written by M.C.Gregorie.

               Version history
               
               1.0   25/07/2011   Initial release

   <kbd>
   <b>environ - C programming support functions</b><br>
   Copyright (C) 2005-11  Martin C Gregorie
   
   This program is free software; you can redistribute it and/or
   modify it under the terms of the Lesser GNU General Public License.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
  
   You should have received a copy of the Lesser GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
   </kbd>
  
   <p>Contact Martin Gregorie at <i>martin@gregorie.org</i></p>
*/

#define VERSION         "1.0"
#define COPYRIGHT       "(c) M.C.Gregorie, 2011"

#ifndef TRUE
#define TRUE       1
#endif

#ifndef FALSE
#define FALSE      0
#endif

#define FLAGCNT    2

#define HELP       0      /* -? help */
#define DEBUG      1      /* -d debug mode */

#define MAYBEMARK  '%'
#define BADMARK    '!'
#define OK         ' '
#define OPTLIST    "?d"

#define INCORRECT  -100

#include <environ.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>

#define _XOPEN_SOURCE_500
#include <time.h>

#include "adjustdate.h"

int readargs(int argc, char *argv[], int flags[]);
void showhelp();
int runtest(char *script, int debug);

/*
   This function scans the command line for options and does
   all the associated setup.
*/
int readargs(int argc, char *argv[], int flags[])
{
   int i; 
   int opt;

   /* initialise flags */

   for (i=0 ; i<FLAGCNT ; i++) flags[i] = FALSE;

   /* set up options from the command line */

   optmaybe = MAYBEMARK;
   optbad = BADMARK;
   optind = 1;
   
   while ((opt=getopt(argc,argv,OPTLIST)) != EOF)   
   {
      switch (opt) {
         case 0:         continue;
         case BADMARK:   return(opt);
         case '?':       flags[HELP] = TRUE;       
                         break;
         case 'd':       flags[DEBUG]++;
                         break;
         default :       error(argv[0],
                               "impossible happened parsing options",
                               "");
      }
   }
   return(OK);
}

/*
   Show the punter what the options are
*/
void showhelp()
{
   printf("\ntestadjustdate v%s %s\n\n",VERSION,COPYRIGHT);
   printf("Syntax  : testadjustdate [<opts>] script ...\n");
   printf("Function: Adjustdate package test harness runs test\n");
   printf("          scripts and displays test results.\n");
   printf("Options :\n");
   printf("     -d           debug mode\n");
   printf("if given\n");
}

/*
   The main program starts here
   ----------------------------
*/
int main(int argc, char *argv[])
{
   int   flags[FLAGCNT],
         argtype,
         reply;

   /*
      Parse and set up command options
   */
   setprog(argv[0]);
   if (readargs(argc,argv,flags) == BADMARK)
   {
      return(1);
   }

   /*
      If help was asked for, give it and quit
   */
   if (flags[HELP]) 
   {
      showhelp();
      return(0);
   }

   optind = 1;
   while ((argtype = getarg(argc, argv)) >= 0)
   {
      if (argtype > 0)
      {
         reply = runtest(optarg, flags[DEBUG]);
         if (reply)
            break;
      }
   }
   
   return(reply);
}

int runtest(char *script, int debug)
{
   FILE        *f;
   char        line[MAXLINE];
   int         lineno;
   int         linelth;
   int         i;
   char        *s;

   char        *fn;
   char        *p1;
   char        *p2;
   int         n1;
   int         n2;

   time_t      savedate;
   struct tm   inputdate;
   char        *idptr;
   char        *result;
   char        *es;
   int         e;
   int         errcnt;

   lineno = 0;
   errcnt = 0;
   savedate = 0;
      
   f = fopen(script, "r");
   if (f)
   {
      printf("Processing script %s\n", script);
   }
   else
   {
      printf("Can't open %s\n\n", script);
      return errno;
   }

   ajdebug(debug);

   while (fgets(line, MAXLINE, f))
   {
      /*
         Count lines read.
         Remove trailing newlines and spaces.
         Print the line.
      */
      lineno++;
      linelth = strlen(line);
      if (line[linelth-1] == '\n')
      {
      	line[linelth-1] = '\0';
      }

      for (i = strlen(line) -1; i >=0 ;i--)
      {
         if (isspace(line[i]))
            line[i] = '\0';
         else
            break;
      }
            
      printf("%3d: %s\n", lineno, line);

      /*
         Ignore empty lines and those starting with #
      */
      if (line[0] == '#' || strlen(line) == 0)
         continue;

      /*
         If the line has a trailing comment, remove it
      */
      s = strchr(line, '#');
      if (s)
      {
         *s = '\0';
         if (debug > 2)
         {
            printf("Line truncated to '%s'\n", line);
         }
      }

      /*
         Parse the command
      */
      p1 = "";
      p2 = "";
      n1 = 0;
      n2 = 0;
      fn = strtok(line, " \t");
      if (!fn)
      {
         printf("     Error:  No function in this line\n");
         errcnt++;
         continue;
      }
      
      if ((p1 = strtok(NULL, " \t")))
      {
         n1 = atoi(p1);
      }
      else
      {
      	p1 = "";
      }

      if ((p2 = strtok(NULL, " \t")))
      {
         n2 = atoi(p2);
      }
      else
      {
      	p2 = "";
      }

      if (debug > 1)
      {
         printf("     Debug:   fn=%s p1='%s' p2='%s'\n", fn, p1, p2);
         printf("                    n1=%d   n2=%d\n", n1, n2);
      }

      /*
         Identify the function to be run and do so, reporting results
      */
      if (strcmp("ajformatdate", fn) == 0)
      {
      	 if (strcmp(p1, "DATE") == 0)
            result = ajformatdate("%04Y-%02m-%02e");
      	 else
      	 if (strcmp(p1, "TIME") == 0)
            result = ajformatdate("%02H:%02M:%02S");
      	 else
      	 if (strcmp(p1, "SECONDS") == 0)
            result = ajformatdate("%s");
      	 else
      	 if (strcmp(p1, "PLAIN") == 0)
            result = ajformatdate("%04Y-%02m-%02e %02H:%02M:%02S");
      	 else
      	 if (strcmp(p1, "FANCY") == 0)
            result = ajformatdate("%02e%b%04Y %H:%M:%S %Z");
      	 else
      	    result = ajformatdate("%c");

         printf("     Result: %s\n", result);
      }
      else
      if (strcmp("ajgetdate", fn) == 0)
      {
         savedate = ajgetdate();
         printf("     Result: %d - %s", savedate, ctime(&savedate));
      }
      else
      if (strcmp("ajmonth", fn) == 0)
      {
      	 if (strcmp(p2, "FIRSTDAY") == 0)
      	   ajmonth(n1, FIRSTDAY);
      	 else
      	 if (strcmp(p2, "LASTDAY") == 0)
      	   ajmonth(n1, LASTDAY);
      	 else
      	 if (strcmp(p2, "KEEPDAY") == 0)
      	   ajmonth(n1, KEEPDAY);
      	 else
      	 if (strcmp(p2, "KEEPDATE") == 0)
      	   ajmonth(n1, KEEPDATE);
      	 else
      	   ajmonth(n1, n2);
      }
      else
      if (strcmp("ajoffsetdate", fn) == 0)
      {
      	 if (strcmp(p2, "DAY") == 0)
      	   ajoffsetdate(n1, DAY);
      	 else
      	 if (strcmp(p2, "HOUR") == 0)
      	   ajoffsetdate(n1, HOUR);
      	 else
      	 if (strcmp(p2, "MIN") == 0)
      	   ajoffsetdate(n1, MIN);
      	 else
      	 if (strcmp(p2, "SEC") == 0)
      	   ajoffsetdate(n1, SEC);
      	 else
      	 if (strcmp(p2, "INCORRECT") == 0)
      	   ajoffsetdate(n1, INCORRECT);
      	 else
      	   ajoffsetdate(n1, n2);
      }
      else
      if (strcmp("ajsetdate", fn) == 0)
      {
         if (strcmp(p1, "SAVEDATE") == 0)
         {
            ajsetdate(savedate);
         }
         else
         {
            idptr = (char*)strptime(p1, "%Y-%m-%e,%H:%M:%S", &inputdate);
            if (idptr != NULL)
            {
               savedate = mktime(&inputdate);
               printf("     Setting: %d : %s", savedate, ctime(&savedate));
               ajsetdate(savedate);
            }
            else
            {
               printf("     Script error: invalid date [%s]\n", p1);
               printf("                   format must be %s\n",
                      "yyyy-mm-dd,hh:mm:ss");
               errcnt++;
            }
         }
      }
      else
      if (strcmp("ajsetnow", fn) == 0)
      {
         ajsetnow();
      }
      else
      if (strcmp("ajtruncate", fn) == 0)
      {
         if (strcmp(p1, "ON") == 0)
            ajtruncate(ON);
         else
         if (strcmp(p1, "OFF") == 0)
            ajtruncate(OFF);
         else
         if (strcmp(p1, "INCORRECT") == 0)
            ajtruncate(INCORRECT);
         else
            ajtruncate(n1);
      }
      else
      if (strcmp("ajyear", fn) == 0)
      {
      	 if (strcmp(p2, "FIRSTDAY") == 0)
      	   ajyear(n1, FIRSTDAY);
      	 else
      	 if (strcmp(p2, "LASTDAY") == 0)
      	   ajyear(n1, LASTDAY);
      	 else
      	 if (strcmp(p2, "KEEPDATE") == 0)
      	   ajyear(n1, KEEPDATE);
      	 else
      	 if (strcmp(p2, "KEEPDAY") == 0)
      	   ajyear(n1, KEEPDAY);
      	 else
      	   ajyear(n1, n2);
      }
      else
      {
         printf("     Error: unknown function name\n");
         errcnt++;
         continue;
      }

      /*
         See if the function threw an error and report it
      */
      e = ajerror();
      if (e)
      {
         es = ajgeterror();
         printf("     Error:  %s\n", es);
         errcnt++;
      }
   }

   /*
      Run complete
   */
   printf("Script ended: %d errors\n\n", errcnt);
   fclose(f);
   return 0;
}


