/*

  todo
  ----

  remove repetitive code,  structure code more..

  set F-<flag> to NULL or FALSE between loaded flags!! if you had the following config
  you'd get problems

    Get_RenameDIZ_1=TRUE
                           > as _2 is missing it'd be TRUE where it should default to FALSE
    Get_RenameDIZ_3=TRUE

  ExtractDIZ/AddDIZ
  ====================

  This door has two modes, extract diz and add diz, I've written one door for the
  two functions as alot of the code is the same.

  Program to extract the file_id.diz from a file, store the fileid in the node's work
  dir as <filename>.diz

  Options
  =======

    N_ND->ActiveDoor->SystemOptions
    -------------------------------

    UPDATE|EXTRACT

    Door Options (Command Line)
    ---------------------------

2   <filename>

3   <workdir>

4   <playpen dir>

5   <filename without .extension>

6   <.extension without filename and without the .>

7   [NOUSER]

    Note: Hey, I really couldn't think of any other settings that might be usefull..
    you can even write a damn AmigaDOS script to extract file_id's with all those
    parameters! hehehe


*/


#include <exec/types.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/alib_protos.h>

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <time.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: ExtractDIZ "RELEASE_STR;

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

struct BBSGlobalData *BBSGlobal=NULL;
struct NodeData *N_ND=NULL;
int N_NodeNum=-1;
char outstr[1024]; // temp string for displaying text..
  char tmpfilename[30];


char     *F_Ext=NULL;
char     *F_Type=NULL;
char     *F_AddDIZ=NULL;
char     *F_GetDIZ=NULL;
V_BIGNUM  F_MaxDIZLines=0;
V_BOOL    F_Add_CDToWork=FALSE;
V_BOOL    F_Get_CDToWork=FALSE;
V_BOOL    F_Add_CDToPlayPen=FALSE;
V_BOOL    F_Get_CDToPlayPen=FALSE;
V_BOOL    F_Get_RenameDIZ=FALSE;
V_BOOL    F_Add_RenameDIZ=FALSE;

BOOL UserAround=TRUE;

LONG __stack=16384;   // needs big stack for running external commands!


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

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

  if (num) printf("Door Error = %d\n",num);

  exit(0);
}

static VOID init(char *name)
{
  if(!(HBBSCommonBase = OpenLibrary("HBBSCommon.library",0)))
  {
    cleanup(1);
  }

  if (!(HBBS_InitCommon()))
  {
    cleanup(2);
  }

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

    if (!(HBBS_InitDoor(N_NodeNum,name)))
    {
      cleanup(4);
    }
  SetProgramName(name);
}

#define MODE_UPDATE 1
#define MODE_EXTRACT 2


/*
; {A} is replaced with the full path and filename of the uploaded file
; {F} is replaced with the filename of the uploaded file
; {N} is replaced with the filename (but not the extension) of the file
; {E} is replaced with the extension of the file
; {W} is replaced with the full path of the WORK directory
; {P} is replaced with the playpen direcotry
; {D} is replaced with the full path and filename of the DIZ file to be added/extracted
*/

void DeleteOldDIZ(int argc,char *argv[])
{
  char tmpstr[2048];

  strcpy(tmpstr,argv[3]);
  strcat(tmpstr,argv[2]);
  strcat(tmpstr,".ADD");
  DeleteFile(tmpstr); //remove old file

  strcpy(tmpstr,argv[3]);
  strcat(tmpstr,argv[2]);
  strcat(tmpstr,".MISC");
  DeleteFile(tmpstr); //remove old file

  strcpy(tmpstr,argv[3]);
  strcat(tmpstr,argv[2]);
  strcat(tmpstr,".DIZ");
  DeleteFile(tmpstr); //remove old file


}

void ExtractDIZ(int argc,char *argv[], char *TypeOfFile )
{
  char runcmd[2048]; //*W* define me
  char tmpstr[2048];


  if (UserAround)
  {
    sprintf(tmpstr,ANSI_RESET ANSI_FG_GREEN "Extracting File ID for "ANSI_ITALIC ANSI_FG_BLUE "%s" ANSI_RESET ANSI_FG_GREEN " \"%s\" .. ",TypeOfFile,argv[2]);
    DOOR_WriteText(tmpstr);
  }

  strcpy(tmpstr,argv[3]); // workdir
  strcat(tmpstr,"file_id.diz");
  DeleteFile(tmpstr); //remove old file

  strcpy(runcmd,F_GetDIZ);

  strcpy(tmpstr,argv[4]);
  strcat(tmpstr,argv[2]);
  replace(runcmd,runcmd,"{A}",tmpstr); //full path + filename

  replace(runcmd,runcmd,"{F}",argv[2]); //filename

  replace(runcmd,runcmd,"{N}",argv[5]); //filename without .extension

  replace(runcmd,runcmd,"{E}",argv[6]); //extension with the .

  replace(runcmd,runcmd,"{W}",argv[3]); //workdir

  replace(runcmd,runcmd,"{P}",argv[4]); //playpen dir

  strcpy(tmpstr,argv[3]);
  strcat(tmpstr,argv[2]);
  strcat(tmpstr,".ADD");
  DeleteFile(tmpstr); //remove old file

  strcpy(tmpstr,argv[3]);
  strcat(tmpstr,argv[2]);
  strcat(tmpstr,".MISC");
  DeleteFile(tmpstr); //remove old file

  strcpy(tmpstr,argv[3]);
  strcat(tmpstr,argv[2]);
  strcat(tmpstr,".DIZ");
  DeleteFile(tmpstr); //remove old file

  replace(runcmd,runcmd,"{D}",tmpstr); //workdir + filename + .DIZ

  sprintf(tmpfilename,"T:HBBS/UD%ld.TMP",N_ND->NodeNum);
  HBBS_DosCommand(runcmd,RDC_NONE,tmpfilename);
  DeleteFile(tmpfilename);

  if (F_Get_RenameDIZ)
  {
    strcpy(runcmd,argv[3]);
    strcat(runcmd,"FILE_ID.DIZ");
    Rename(runcmd,tmpstr);         // *** tmpstr must contain {D} still... ^^^
  }

  if (UserAround) DOOR_WriteText("Done\r\n");
}

void UpdateDIZ(int argc,char *argv[])
{
  char runcmd[2048]; //*W* define me
  char tmpstr[1048];
  char tmpstr2[1048];

  if (UserAround) DOOR_WriteText(ANSI_RESET "Updating File ID..");
  strcpy(tmpstr,argv[3]); // workdir
  strcat(tmpstr,"file_id.diz");
  DeleteFile(tmpstr); //remove old file

  strcpy(runcmd,F_AddDIZ);

  strcpy(tmpstr,argv[4]);
  strcat(tmpstr,argv[2]);
  replace(runcmd,runcmd,"{A}",tmpstr); //full path + filename

  replace(runcmd,runcmd,"{F}",argv[2]); //filename

  replace(runcmd,runcmd,"{N}",argv[5]); //filename without .extension

  replace(runcmd,runcmd,"{E}",argv[6]); //.extenstion

  replace(runcmd,runcmd,"{W}",argv[3]); //workdir

  replace(runcmd,runcmd,"{P}",argv[4]); //playpen dir

  strcpy(tmpstr,argv[3]);
  strcat(tmpstr,argv[2]);
  strcat(tmpstr,".ADD");
  replace(runcmd,runcmd,"{D}",tmpstr); //workdir + filename + .ADD

  if (F_Add_RenameDIZ) // rename <file>.ADD to file_id.diz before adding ?
  {
    strcpy(tmpstr2,argv[3]);
    strcat(tmpstr2,"FILE_ID.DIZ");
    Rename(tmpstr,tmpstr2);         // *** tmpstr must contain {D} still... ^^^
  }

  sprintf(tmpfilename,"T:HBBS/UD%ld.TMP",N_ND->NodeNum);
  HBBS_DosCommand(runcmd,RDC_NONE,tmpfilename);
  DeleteFile(tmpfilename);

  if (UserAround) DOOR_WriteText("Done\r\n");
}


void DoorMain(int argc,char *argv[])
{
  BPTR FL,NFL;
  struct CfgFileData *CfgFile=NULL;
  int ftype=1;
  char optionname[30];

  short Mode=0;

  BOOL Done=FALSE,allfound;

//  DOOR_WriteText("\r\n[0;36m-=[ [37;44m [0;3;37;44mHydra ExtractDIZ V1.0[0;37;44m [36;40m ]=-[35m ======== [36m-=[ [37;44m [0;3;37;44m(C) 1995 Deluxe Software Ltd[0;37;44m [36;40m ]=-\r\n\r\n");

  if (stricmp("EXTRACT",N_ND->ActiveDoor->SystemOptions)==0)
  {
    Mode=MODE_EXTRACT;
    DeleteOldDIZ(argc,argv);
  }
  if (stricmp("UPDATE",N_ND->ActiveDoor->SystemOptions)==0) Mode=MODE_UPDATE;


  if (!Mode)
  {
    if (UserAround) DOOR_SysopText(ANSI_RESET ANSI_FG_RED "Invalid/No Mode specified!\r\n");
  }
  else
  {
    if (argc==7 || argc==8)
    {

      if (CfgFile=HBBS_LoadConfig("HBBS:System/FileID",LCFG_NONE))
      {
        do
        {
          sprintf(optionname,"FileExtension_%d",ftype);
          if (HBBS_GetSetting(CfgFile,(void *)&F_Ext,VTYPE_STRING,optionname,OPT_SINGLE))
          {
            allfound=FALSE;
            sprintf(optionname,"FileType_%d",ftype);
            if (HBBS_GetSetting(CfgFile,(void *)&F_Type,VTYPE_STRING,optionname,OPT_SINGLE))
            {
              sprintf(optionname,"AddDIZ_%d",ftype);
              if (HBBS_GetSetting(CfgFile,(void *)&F_AddDIZ,VTYPE_STRING,optionname,OPT_SINGLE))
              {
                sprintf(optionname,"GetDIZ_%d",ftype);
                if (HBBS_GetSetting(CfgFile,(void *)&F_GetDIZ,VTYPE_STRING,optionname,OPT_SINGLE))
                {
                  sprintf(optionname,"MaxDIZLines_%d",ftype);
                  HBBS_GetSetting(CfgFile,(void *)&F_MaxDIZLines,VTYPE_BIGNUM,optionname,OPT_SINGLE);
                  sprintf(optionname,"Add_CDToWork_%d",ftype);
                  HBBS_GetSetting(CfgFile,(void *)&F_Add_CDToWork,VTYPE_BOOL,optionname,OPT_SINGLE);
                  sprintf(optionname,"Get_CDToWork_%d",ftype);
                  HBBS_GetSetting(CfgFile,(void *)&F_Get_CDToWork,VTYPE_BOOL,optionname,OPT_SINGLE);
                  sprintf(optionname,"Add_CDToPlayPen_%d",ftype);
                  HBBS_GetSetting(CfgFile,(void *)&F_Add_CDToPlayPen,VTYPE_BOOL,optionname,OPT_SINGLE);
                  sprintf(optionname,"Get_CDToPlayPen_%d",ftype);
                  HBBS_GetSetting(CfgFile,(void *)&F_Get_CDToPlayPen,VTYPE_BOOL,optionname,OPT_SINGLE);
                  sprintf(optionname,"Get_RenameDIZ_%d",ftype);
                  HBBS_GetSetting(CfgFile,(void *)&F_Get_RenameDIZ,VTYPE_BOOL,optionname,OPT_SINGLE);
                  sprintf(optionname,"Add_RenameDIZ_%d",ftype);
                  HBBS_GetSetting(CfgFile,(void *)&F_Add_RenameDIZ,VTYPE_BOOL,optionname,OPT_SINGLE);

                  // Required and Optional params are now loaded..
                  allfound=TRUE;

                  if (stricmp(F_Ext,argv[6])==0)
                  {
                    if (Mode==MODE_EXTRACT)
                    {
                      if (F_Get_CDToPlayPen)
                      {
                        if (FL=Lock(N_ND->NodeSettings.NodePlayPen,ACCESS_READ))
                        {
                          NFL=CurrentDir(FL);
                          UnLock(NFL);
                          ExtractDIZ(argc,argv,F_Type);
                        } else if (UserAround) DOOR_WriteText("Lock(<Playpen>) Failed!\r\n");
                      }
                      else
                      {
                        if (F_Get_CDToWork)
                        {

                          sprintf(outstr,"%sWork/",N_ND->NodeLocation);
                          if (FL=Lock(outstr,ACCESS_READ))
                          {
                            NFL=CurrentDir(FL);
                            UnLock(NFL);
                            ExtractDIZ(argc,argv,F_Type);
                          } else if (UserAround) DOOR_WriteText("Lock(<playpen>) Failed!\r\n");
                        }
                        else ExtractDIZ(argc,argv,F_Type);
                      }
                    }
                    else
                    {
                      if (Mode==MODE_UPDATE)
                      {
                        if (F_Get_CDToPlayPen)
                        {
                          if (FL=Lock(N_ND->NodeSettings.NodePlayPen,ACCESS_READ))
                          {
                            NFL=CurrentDir(FL);
                            UnLock(NFL);
                            UpdateDIZ(argc,argv);
                          } else if (UserAround) DOOR_WriteText("Lock(<Playpen>) Failed!\r\n");
                        }
                        else
                        {
                          if (F_Get_CDToWork)
                          {

                            sprintf(outstr,"%sWork/",N_ND->NodeLocation);
                            if (FL=Lock(outstr,ACCESS_READ))
                            {
                              NFL=CurrentDir(FL);
                              UnLock(NFL);
                              UpdateDIZ(argc,argv);
                            } else if (UserAround) DOOR_WriteText("Lock(<playpen>) Failed!\r\n");
                          }
                          else UpdateDIZ(argc,argv);
                        }
                      }

                    }

                  }
                }
              }
            }
            if (!allfound)
            {
              sprintf(outstr,ANSI_RESET ANSI_FG_RED "Error In Configuration when loading options for\r\n"
                             "%s files in the FileID Config File..\r\n",F_Ext);
              if (UserAround) DOOR_SysopText(outstr);
            }
          } else Done=TRUE;

          FreeStr(F_Ext); F_Ext=NULL;
          FreeStr(F_Type); F_Type=NULL;
          FreeStr(F_AddDIZ); F_AddDIZ=NULL;
          FreeStr(F_GetDIZ); F_GetDIZ=NULL;
          ftype++;
        } while (!Done);

        HBBS_FlushConfig(CfgFile);


      }
      else if (UserAround) DOOR_SysopText(ANSI_RESET ANSI_FG_RED "Error Loading Configuration File!\r\n");
    }
    else if (UserAround) DOOR_SysopText(ANSI_RESET ANSI_FG_RED "Invalid Door Options!\r\n");
  }
}

int main(int argc,char *argv[])
{
  if (sscanf(argv[1],"%d",&N_NodeNum)==0)
  {
    printf("Invalid/No Paramaters for door!\n");
    exit (20);
  }

  if (stricmp("NOUSER",argv[argc-1])==0) UserAround=FALSE;

  init("ExtractDIZ");

  if (BBSGlobal=HBBS_GimmeBBS())
  {
    if (N_ND=HBBS_NodeDataPtr(N_NodeNum)) // this should not fail in normal circumstances..
    {
      if (N_ND->OnlineStatus!=OS_ONLINE) UserAround=FALSE;
      DoorMain(argc,argv);
    }
  }
  cleanup(0);
}
