#include <CrashTick.h>

#include <clib/dos_protos.h>
#include <clib/exec_protos.h>

extern struct Config config;

int IsFlow(UBYTE *file)
{
   UBYTE c;
   UBYTE ext[4];
   UBYTE dots;

   dots=0;
   c=0;

   while(c<strlen(file) && dots!=4)
   {
      if(file[c]=='.')
         dots++;

      else if(file[c]<'0' || file[c]>'9') return(FALSE);

      c++;
   }

   if(dots!=4) return(FALSE);
   if(strlen(&file[c])!=3) return(FALSE);

   strcpy(ext,&file[c]);

   if(stricmp(ext,"FLO")==0) return(TRUE);
   if(stricmp(ext,"HLO")==0) return(TRUE);
   if(stricmp(ext,"CLO")==0) return(TRUE);
   if(stricmp(ext,"DLO")==0) return(TRUE);

   return(FALSE);
}

short Maint(void)
{
   uchar filename[200];
   struct jbList tickdirlist,flowdirlist;
   struct FileEntry *fe,*te;
   BPTR fh;
   BOOL brk;
   struct DateStamp ds;

   LogWrite(4,TICKINFO,getString(TXT_MAINT));

   if(config.cfg_Filebase[0] == 0)
   {
      LogWrite(1,TICKERR,getString(ERR_MAINT_NO_FILEBASE));
      return(10);
   }

   if(!(jbReadDir(config.cfg_Filebase,&tickdirlist,NULL)))
   {
      LogWrite(1,TICKERR,getString(ERR_NO_DIRECTORY),config.cfg_Filebase);
      return(10);
   }

   if(!(jbReadDir(config.cfg_Outbound,&flowdirlist,IsFlow)))
   {
      LogWrite(1,TICKERR,getString(ERR_NO_DIRECTORY),config.cfg_Outbound);
      jbFreeList(&tickdirlist,sizeof(struct FileEntry));
      return(10);
   }

   /* Uses the field size in struct NodeEntry as a BOOL IsInFlow */

   for(fe=(struct FileEntry *)tickdirlist.First;fe;fe=fe->Next)
      fe->Size=FALSE;

   brk=FALSE;

   for(fe=(struct FileEntry *)flowdirlist.First;fe && !brk;fe=fe->Next)
   {
      strcpy(filename,config.cfg_Outbound);
      AddPart(filename,fe->Name,200);

LogWrite(6,TICKINFO,"Debug: Reading flow file %s",filename);

      if(!(fh=Open(filename,MODE_OLDFILE)))
      {
         LogWrite(1,TICKERR,getString(ERR_FAILED_OPEN_READ),filename);
         jbFreeList(&tickdirlist,sizeof(struct FileEntry));
         jbFreeList(&flowdirlist,sizeof(struct FileEntry));
         return(10);
      }

      while(FGets(fh,filename,200) && filename[0]!=0 && !brk)
      {
         while(filename[strlen(filename)-1]==10 || filename[strlen(filename)-1]==13)
            filename[strlen(filename)-1]=0;

         if(filename[0]=='#')
            strcpy(filename,&filename[1]);

         if(filename[0]=='-')
            strcpy(filename,&filename[1]);

         if(filename[0]=='^')
            strcpy(filename,&filename[1]);

LogWrite(6,TICKINFO,"Debug:  Found file: %s",filename);

         for(te=(struct FileEntry *)tickdirlist.First;te;te=te->Next)
         {
            if(stricmp(te->Name,FilePart(filename)) == 0)
            {
               BPTR l1,l2;
               uchar filename2[200];

               /* Make an extra check */

               if(!te->Size)
               {
                  strcpy(filename2,config.cfg_Filebase);
                  AddPart(filename2,te->Name,200);

                  l1=Lock(filename,SHARED_LOCK);
                  l2=Lock(filename2,SHARED_LOCK);

                  if(l1 && l2)
                  {
                     if(SameLock(l1,l2)==LOCK_SAME)
{
                        te->Size=TRUE;
LogWrite(6,TICKINFO,"Debug:   %s will not be deleted",te->Name);
}
                  }

                  if(l1) UnLock(l1);
                  if(l2) UnLock(l2);
               }
            }
         }

         if(SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
            brk=TRUE;
      }

      Close(fh);
   }

   if(brk)
   {
      jbFreeList(&tickdirlist,sizeof(struct FileEntry));
      jbFreeList(&flowdirlist,sizeof(struct FileEntry));
      return(0);
   }

   DateStamp(&ds);

   for(fe=(struct FileEntry *)tickdirlist.First;fe && !brk;fe=fe->Next)
   {
      if(SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
         brk=TRUE;
   
      if(stricmp(fe->Comment,"Filebase")==0 && !brk)
      {
         strcpy(filename,config.cfg_Filebase);
         AddPart(filename,fe->Name,200);

         if(!fe->Size)
         {
            LogWrite(5,TICKINFO,getString(TXT_MAINT_DELETE_SENT),fe->Name);
            DeleteFile(filename);
         }
         else if(config.cfg_MaxWaitPickup != 0 && (ds.ds_Days-fe->Date.ds_Days) > config.cfg_MaxWaitPickup)
         {
            LogWrite(5,TICKINFO,getString(TXT_MAINT_DELETE_TOO_OLD),fe->Name);
            DeleteFile(filename);
         }
      }
   }

   jbFreeList(&tickdirlist,sizeof(struct FileEntry));
   jbFreeList(&flowdirlist,sizeof(struct FileEntry));
   return(0);
}
