/* **** Includes *********************************************************** */

#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 <HBBS/ANSI_Codes.h>
#include <HBBS/Defines.h>
#include <HBBS/Access.h>
#include <HBBS/types.h>
#include <HBBS/structures.h>

#include <HBBS/Hbbscommon_protos.h>
#ifdef __SASC
#include <HBBS/hbbscommon_pragmas_sas.h>
#else
#include <HBBS/hbbscommon_pragmas_stc.h>
#endif

#include <HBBS/Hbbsnode_protos.h>
#ifdef __SASC
#include <HBBS/Hbbsnode_pragmas_sas.h>
#else
#include <HBBS/Hbbsnode_pragmas_stc.h>
#endif

#include <HBBS/release.h>
char *versionstr="$VER: TagFile "RELEASE_STR;

/* **** Variables ********************************************************** */


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

struct BBSGlobalData *BBSGlobal = NULL;
struct NodeData *N_ND           = NULL;
int    N_NodeNum                = -1;
char   outstr[1024];

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

int    gargc;         // these are just copies of main()'s argc and argv..
char   **gargv;

/* **** Functions ********************************************************** */


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

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);
}

BOOL AlreadyTagged(UBYTE *fullname)
{
  struct Node *node;
  BOOL Found=FALSE;

  for (node=N_ND->TaggedFileList->lh_Head;!Found && node->ln_Succ;node=node->ln_Succ)
  {
    Found = (stricmp(fullname,node->ln_Name)==0);
  }
  return(Found);
}

void TagPrompt( void )
{
  DOOR_WriteText(ANSI_FG_YELLOW "Tagging "ANSI_FG_BLUE"> "ANSI_FG_WHITE);
}

void DoorMain(int argc,char *argv[])
{
  short loop;
  struct TaggedFile *filetagnode;
  char filename[1024],fullname[1024],tmpstr[BIG_STR];
  V_BIGNUM ConfNum,filesize;
  BOOL FileOK;

  V_BIGNUM tagged=0;

//  DOOR_WriteText("\r\n[0;36m-=[ [37;44m [0;3;37;44mHydra AddTag 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");


  for(loop=2;loop<argc;loop++)
  {
    if (loop==2) TagPrompt();

    if (sscanf(argv[loop],"C=%ld,N=%s",&ConfNum,filename)==2)
    {
      RemoveSpaces(filename);
      DOOR_WriteText(filename);

      FileOK=FALSE;


      // check existence of file.
      if (ConfNum>0)
      {
        if (HBBS_FindConfFile(ConfNum,filename,fullname))
        {
          FileOK=TRUE;
        }
      }
      else
      {
        if (PathOK(filename))
        {
          FileOK=TRUE;
          strcpy(fullname,filename);
        }
      }

      if (FileOK)
      {
        if (AlreadyTagged(fullname))
        {
          DOOR_WriteText(ANSI_FG_BLUE" - "ANSI_FG_CYAN"File Already Tagged!\r\n"ANSI_FG_WHITE);
          if (loop<argc-1) TagPrompt();
        }
        else
        {

          filesize=HBBS_GetFileSize(fullname);

          // Call the door OKTOTAG <filename> <fullname> <filesize> <confnum>
          // it is the responsibility of the OKTOTAG door to display errormessages as to why the
          // file cannot be tagged.

          sprintf(tmpstr,"%s %s %ld %ld",filename, fullname, filesize, ConfNum);
          DOOR_SystemDoor("OKtoTag",tmpstr);

          if (!(stricmp(N_ND->DoorReturn,"NO")==0)) // return NO to not tag file, anything else or no door to tag it.
          {
            if (filetagnode=AllocVec(sizeof(struct TaggedFile),MEMF_PUBLIC|MEMF_CLEAR))
            { 
              if (filetagnode->node.ln_Name=DupStr(fullname))
              {
                 
                if (ConfNum>0) filetagnode->WarezFile=TRUE; else filetagnode->WarezFile=FALSE;
                filetagnode->ConferenceNum=ConfNum;


                filetagnode->FileSize=filesize;

                AddTail(N_ND->TaggedFileList,(struct Node*) filetagnode);
                N_ND->TaggedFiles++;
                tagged++;
                
                if (loop<argc-1) DOOR_WriteText(ANSI_FG_BLUE","ANSI_FG_WHITE);
              }
              else
              {
                FreeVec(filetagnode);
              }
            }
          }
        }
      }
      else
      {
        DOOR_WriteText(ANSI_FG_BLUE" - "ANSI_FG_CYAN"File Not Found!\r\n"ANSI_FG_WHITE);
        if (loop<argc-1) TagPrompt();
      }
    }
  }
  DOOR_WriteText("\r\n");
  
  sprintf(outstr,"%ld",tagged);
  
  // tell FreeDL to check the last few files that we tagged.
  
  if (tagged == 1)
  {
    DOOR_SystemDoor("FreeDL","LASTONLY");
  }
  
  if (tagged > 1)
  {
    DOOR_SystemDoor("FreeDL",outstr);
  }
  
  
  // returns the amount of files that have been tagged, as a string.
  DOOR_Return(outstr);
}

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

  if (BBSGlobal=HBBS_GimmeBBS())
  {
    if (N_ND=HBBS_NodeDataPtr(N_NodeNum)) // this should not fail in normal circumstances..
    {
      DoorMain(argc,argv);
    }
  }
  cleanup(0);
}
