#include "DLGHub.h"

#include <link/io.h>

BOOL EvaluateDay(int, char *);

struct   Config   *CFG = NULL;

/// LoadConfig
int LoadConfig(void)
{
   BOOL  Skip = FALSE;

   BPTR  fh = NULL;

   int   cnt = 0;
   int   index = 0;
   int   ind = -1;
   int   Today;

   char  buf[1000];

   unsigned char clock[8];

   getclk(clock);

   Today = clock[0];

   fh = Open("FIDO:DLGMail.Hub",MODE_OLDFILE);

   if(!fh) return(-1);

/// Count up FOUND entries
   while(FGets(fh,buf,1000))
   {
      Chk_Abort();

      cnt++;

      StripSpaces(buf);

      if(strlen(buf) <= 1) continue;
      if(!Strnicmp(buf,";",1)) continue;

      if(!Strnicmp(buf,"FOUND",5))
      {
         index++;
         continue;
      }

      if(!Strnicmp(buf,"END",3)) break;
   }
//-

/// Allocate Config struct in memory

   CFG = calloc(index,sizeof(struct Config));

   if(!CFG)
   {
      Log(" ! Not enough memory to load config!");
      Close(fh);
      return(-1);
   }
//-

/// Now load up config
   Seek(fh,0,OFFSET_BEGINNING);

   while(FGets(fh,buf,1000))
   {
      char *t;

      Chk_Abort();

      cnt++;

      StripSpaces(buf);

      if(strlen(buf) <= 1) continue;
      if(!Strnicmp(buf,";",1)) continue;

      t = strdup(strtok(buf,"\n"));

///   DAY
      if(!Strnicmp(t,"DAY",3))
      {
         if(EvaluateDay(Today,t))
            Skip = FALSE;
         else
            Skip = TRUE;
      }
//-

///   FOUND
      if(!Strnicmp(t,"FOUND",5))
      {
         int c;
         char *p[5];

         ind++;

         if(Skip)
         {
            CFG[ind].Skip = TRUE;
            continue;
         }

         c = ArgParse(t,p,3);

         if(c < 2)
         {
            ASPrintf(NULL,logstring," ! Error parsing config file at line %ld!",cnt);
            Log(logstring);
            AFPrintf(NULL,sout,"Error parsing config file at line %ld!\nExiting\n",cnt);
            Close(fh);
            return(-1);
         }

         stcgfp(CFG[ind].Dir,p[1]);
         stcgfn(CFG[ind].Pat,p[1]);
         CFG[ind].Size = 0;

         CFG[ind].clist = calloc(1,sizeof(struct List));
         NewList(CFG[ind].clist);

         continue;
      }
//-

///   IfSize
      if(!Strnicmp(t,"IfSize",6))
      {
         int c;
         char *p[5];

         if(Skip)
            continue;

         c = ArgParse(t,p,3);

         if(c < 2)
         {
            ASPrintf(NULL,logstring," ! Error parsing config file at line %ld!",cnt);
            Log(logstring);
            AFPrintf(NULL,sout,"Error parsing config file at line %ld!\nExiting\n",cnt);
            Close(fh);
            return(-1);
         }

         CFG[ind].Size = atol(p[1]);
         continue;
      }
//-

///   Legal exec keywords
      if(!Strnicmp(t,"Comment",7)   ||
         !Strnicmp(t,"Delete",6)    ||
         !Strnicmp(t,"Rename",6)    ||
         !Strnicmp(t,"Copy",4)      ||
         !Strnicmp(t,"RCopy",5)     ||
         !Strnicmp(t,"Move",4)      ||
         !Strnicmp(t,"RMove",5)     ||
         !Strnicmp(t,"Notify",6)    ||
         !Strnicmp(t,"EventLog",8)  ||
         !Strnicmp(t,"Script",6)    ||
         !Strnicmp(t,"Hatch",5)
        )
      {
         struct Node *n;

         if(CFG[ind].Skip == TRUE) continue;

         n = calloc(1,sizeof(struct Node));
         n->ln_Name = strdup(t);

         AddTail(CFG[ind].clist,n);
         continue;
      }
//-

      if(!Strnicmp(t,"END",3)) break;
}
//-

   Close(fh);

   return(index);
}
//-

/// ShowConfig
void ShowConfig(void)
{
   int i;

   AFPrintf(NULL,sout,"\n");

   for(i = 0; i < Index; i++)
   {
      struct Node *this;
      struct Node *that;

      if(CFG[i].Skip)
      {
         AFPrintf(NULL,sout,"Skipped, wrong day\n");
         continue;
      }

      AFPrintf(NULL,sout,"FIND pattern %s in %s\n",CFG[i].Pat,CFG[i].Dir);

      if(CFG[i].Size > 0)
      {
         AFPrintf(NULL,sout,"\tSize Constraint = %ld\n",CFG[i].Size);
      }
      else
      {
         AFPrintf(NULL,sout,"\tNo size constraint\n");
      }

      if(IsListEmpty(CFG[i].clist))
      {
         AFPrintf(NULL,sout,"\t** No Commands **\n");
         continue;
      }

      this = (CFG[i].clist)->lh_Head;

      while(that = this->ln_Succ)
      {
         AFPrintf(NULL,sout,"\t%s\n",this->ln_Name);
         this = that;
      }

   }

   return;
}
//-

/// EvaluateDay

/*
** Evaluates a string in the format DAY 0 1 2 3 ... to see if one of the
** digits match today's day of week.
**
** day = the current day of week
** DayStr = a string taken from the config file, keyword DAY
**
** returns TRUE if today is found, FALSE if not.
*/

BOOL EvaluateDay(int day, char *DayStr)
{
   char *t[20];

   int i;
   int c;

   c = ArgParse(DayStr,t,19);

   // if no args, DAY is a wild-card. Return TRUE.

   if(c == 1) return(TRUE);

   for(i = 1; i <= c; i++)
   {
      if(day == atoi(t[i])) return(TRUE);
   }

   // if we're this far, the day wasn't found.  Return FALSE.

   return(FALSE);
}
//-

/// FreeCFG
void FreeCFG(void)
{
   int i;
   struct Node *this;
   struct Node *that;

   for(i = 0; i < Index; i++)
   {
      if(CFG[i].Skip)
         continue;

      if(!IsListEmpty(CFG[i].clist))
      {
         this = (CFG[i].clist)->lh_Head;

         while(that = this->ln_Succ)
         {
            Remove(this);
            free(this);
            this = that;
         }
      }

      free(CFG[i].clist);
   }

   free(CFG);
   return;
}
//-


