/*

  StatsGenerator system door

  Params:  [NOUSER] UPDATE <confnum> <creds>

*/


#include <exec/types.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <utility/date.h>

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

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <math.h>

#ifdef __SASC
int CXBRK(void) { return(0); }
int _CXBRK(void) { return(0); }
void chkabort(void) {}
#endif

#include <HBBS/ANSI_Codes.h>
#include <HBBS/Defines.h>
#include <HBBS/types.h>
#include <HBBS/structures.h>
#include <HBBS/hbbscommon_protos.h>
#include <HBBS/hbbscommon_pragmas.h>
#include <HBBS/Hbbsnode_protos.h>
#include <HBBS/Hbbsnode_pragmas.h>
#include <HBBS/release.h>
char *versionstr="$VER: StatsGenerator "RELEASE_STR;

struct Library *HBBSCommonBase  = NULL;
struct Library *HBBSNodeBase    = NULL;

struct BBSGlobalData *BBSGlobal = NULL;
struct NodeData *N_ND           = NULL;
int    N_NodeNum                = -1;
BOOL UserAround = TRUE;

char outstr[1024];
char WeekStartDate[LEN_DATESTR + 1];

long __stack=16*1024; // increase this in 4k incrments if you suffer from
                      // random/suprious crashings after or during the running
                      // of your door.


#define INITERR_NOERROR 0
#define INITERR_NOPARAMS 1
#define INITERR_NOHBBSCOMMON 2
#define INITERR_INITCOMMONFAILED 3
#define INITERR_NOHBBSNODE 4
#define INITERR_INITDOORFAILED 5

static VOID CleanUp(ULONG num)
{
  if (HBBSNodeBase)
  {
    HBBS_CleanUpDoor();
    CloseLibrary (HBBSNodeBase);
  }

  if (HBBSCommonBase)
  {
    HBBS_CleanUpCommon();
    CloseLibrary (HBBSCommonBase);
  }

  switch(num)
  {
    case INITERR_NOERROR:
      exit(0);

    case INITERR_NOPARAMS:
      puts("Bad or no paramaters specified, check your config files\n"
           "(Don't try starting doors from the CLI!)");
      break;

    case INITERR_NOHBBSCOMMON:
      puts("Could not open HBBSCommon.library, check your assign's");
      break;

    case INITERR_INITCOMMONFAILED:
      puts("Could not initialise HBBSCommon.library functions\n"
           "Is HBBS Running ?");
      break;

    case INITERR_NOHBBSNODE:
      puts("Could not open HBBSNode.library, check your assign's");
      break;

    case INITERR_INITDOORFAILED:
      puts("The node specified is either not running or did not want to\n"
           "start this door now. (Don't run doors from the CLI!)");
      break;
  }
  exit(20);
}

static VOID Init(char *name)
{
  if(!(HBBSCommonBase = OpenLibrary("HBBSCommon.library",0)))
  {
    CleanUp(INITERR_NOHBBSCOMMON);
  }

  if (!(HBBS_InitCommon()))
  {
    CleanUp(INITERR_INITCOMMONFAILED);
  }

  if(!(HBBSNodeBase = OpenLibrary("HBBSNode.library",0)))
  {
    CleanUp(INITERR_NOHBBSNODE);
  }

  if (!(HBBS_InitDoor(N_NodeNum,name)))
  {
    CleanUp(INITERR_INITDOORFAILED);
  }

  SetProgramName(name);
}

void UpdateCurrentUser( V_BIGNUM ConfNum, ULONG Bytes )
{
  char statsfilename[100];
  char param[20],item[20];

  V_BIGNUM LastConfBytes = 0;
  V_BIGNUM LastConfFiles = 0;
  struct CfgFileData *cfg;
  char *weekstart = NULL;
  char thisweekstart[LEN_DATESTR+1];

  sprintf(statsfilename,"HBBS:System/Data/Users/%ld/ConfStats.CFG",N_ND->User->CallData->UserID);

  if (!(cfg=HBBS_LoadConfig(statsfilename,LCFG_NONE)))
  {
    cfg = HBBS_CreateConfig(statsfilename);
  }

  if (cfg)
  {

    HBBS_GetWeekStartDate(thisweekstart,HBBS_GetAmigaTime());

    HBBS_GetSetting(cfg,(void *)&weekstart,VTYPE_STRING,"WeekStart",OPT_SINGLE);

    if (weekstart) // did the setting exists ?
    {
      // if so, are we still in the same week ?
      if (stricmp(weekstart,thisweekstart) == 0)
      {
        // yes, so read the old settings in, so they can be updated.
        sprintf(item,"WeekUploadBytes_%ld",ConfNum);
        HBBS_GetSetting(cfg,(void *)&LastConfBytes,VTYPE_BIGNUM,item,OPT_SINGLE);
        sprintf(item,"WeekUploadFiles_%ld",ConfNum);
        HBBS_GetSetting(cfg,(void *)&LastConfFiles,VTYPE_BIGNUM,item,OPT_SINGLE);
      }
      FreeStr(weekstart);
    }

    // update the week, regardless.
    HBBS_AddCfgItem(cfg,"WeekStart",thisweekstart);

    LastConfBytes += Bytes;
    LastConfFiles ++;

    sprintf(item,"WeekUploadBytes_%ld",ConfNum);
    sprintf(param,"%ld",LastConfBytes);
    HBBS_AddCfgItem(cfg,item,param);

    sprintf(item,"WeekUploadFiles_%ld",ConfNum);
    sprintf(param,"%ld",LastConfFiles);
    HBBS_AddCfgItem(cfg,item,param);

    if (UserAround) DOOR_SysopText(ANSI_FG_WHITE"OK\r\n"ANSI_FG_CYAN"Saving...");

    if (HBBS_SaveConfig(cfg))
    {
      if (UserAround) DOOR_SysopText(ANSI_FG_WHITE"OK"ANSI_FG_CYAN"...");
    }
    else
    {
      if (UserAround) DOOR_SysopText(ANSI_FG_WHITE"Failed!"ANSI_FG_CYAN"...");
    }
    HBBS_FlushConfig(cfg);
  }

}

int main(int argc,char *argv[])
{
  LONG startparam=2;
  ULONG Bytes=0;
  V_BIGNUM ConfNum;

  if (argc <= 1)
  {
    CleanUp(INITERR_NOPARAMS);
  }

  /* Get the node number from the paramaters */

  if (sscanf(argv[1],"%d",&N_NodeNum)==0)
  {
    CleanUp(INITERR_NOPARAMS);
  }

  /* Initialise and set the door/program name */

  Init("StatsGenerator");

  if (BBSGlobal=HBBS_GimmeBBS())
  {
    /* Then we need to get the node's data structures for the node this door is going to run on */

    if (N_ND=HBBS_NodeDataPtr(N_NodeNum))
    {
      while (startparam < argc )
      {                  
        if (stricmp(argv[startparam],"NOUSER") == 0)
        {
          startparam++;
          UserAround = FALSE;
        }
        else
        if (stricmp(argv[startparam],"UPDATE") == 0)
        {
          if (UserAround) DOOR_SysopText(ANSI_RESET ANSI_FG_YELLOW "StatsGenerator "ANSI_FG_WHITE"-"ANSI_FG_CYAN" Processing...");

          startparam ++;
          if (1 == sscanf(argv[startparam++],"%ld",&ConfNum))
          {
            if ((ConfNum<1) || (ConfNum>BBSGlobal->Conferences))
            {
              if (UserAround) DOOR_SysopText("Invalid Conference!\r\n");
            }
            else
            {
              if (1 == sscanf(argv[startparam++],"%ld",&Bytes))
              {
                if (Bytes) UpdateCurrentUser(ConfNum,Bytes);
              }
            }
          }
        }
        else // skip unknown params
        {
          startparam ++;
        }
      };

      if (UserAround) DOOR_SysopText(ANSI_FG_WHITE"Done!\r\n");
    }
  }
  /* Cleanup and close libraries */

  CleanUp(INITERR_NOERROR);
}
