/*
	ProblemFileio.c - All I/O with PROBLEM FILE uses these routines
 */
#include <stdio.h>
#include <string.h>
#include "ProblemFileio.h"
#include "../Ctools/ctools.h"
#define FALSE 0
#define TRUE 1

int In_Critical_Section=0;

void PrintProblems(NumProblems,Problem)
int NumProblems;
struct ProblemType *Problem;
{
int i;
char buffer[100];

   for(i=0; i<NumProblems; i++) {
	if ( Problem[i].Name[0]!='\0')
      		printf("TimeStamp=%s Day: %s Time:%s Node: %s [%s] Failed %s Test StatusLine: %s \n",
			ltoa(Problem[i].TimeStamp,buffer),
           		_Day(Problem[i].TimeStamp),_Time(Problem[i].TimeStamp),Problem[i].Name,
			Problem[i].UniqueID,Problem[i].TestName,Problem[i].StatusLine);
   }
}

/***************************************************************************
 * Problem_Exists:  Returns index of Problem if it exists and -1 otherwise *
 ***************************************************************************/
int Problem_Exists(UniqueID,Service,Problem,NumProblems)
char *UniqueID;
char *Service;
struct ProblemType *Problem;
int NumProblems;
{
int i;

   for (i=0; i<NumProblems ; i++) {
       if (strcmp(Problem[i].UniqueID,UniqueID)==0)
          if (strcmp(Problem[i].TestName,Service)==0)
                        return(i);
   }
   return(-1);
}


/*****************************************************************************
 * ReadProblemFile:  Read the Problems from file into our internal format.   *
 *****************************************************************************/
int ReadProblemFile(Problem,file) /* Read and Store hostfile - return # read */
struct ProblemType *Problem;      /* Network Entities Structure Array        */
char *file;                       /* Filename to read these from             */
{
FILE *stream;
char buffer[100],*p;
int Error=FALSE;
int i,line;

	In_Critical_Section=1;
   if ( !lock(file) )
	panic("Read_ProblemFile: PROBLEM.FILE LOCKED");

   if ((stream=fopen(file,"r")) == NULL)
      syserr("fopen PROBLEM FILE");
   for(i=0,line=0;((fgets(buffer,100,stream)!= NULL)&&(i<MAXPROBLEMS));line++){
      if (Error==TRUE) {
      /*   printf("Error in line %d of Problem File - IGNORED\n",line); */
      }
      Error=TRUE;       /* Assume a bad line */
      if (buffer[0]=='#') { Error=FALSE; continue; } /* COMMENT */

      if ( (p=strtok(buffer,DELIMITERS)) == NULL ) continue;
	Problem[i].TimeStamp = atol( p );

      if ( (p=strtok(NULL,DELIMITERS)) == NULL ) continue;
      strncpy(Problem[i].Name,p,MAXNODENAME);      /* Pull off Node name */
      Problem[i].Name[MAXNODENAME-1]='\0';         /* Null Terminate!    */

      if ( (p=strtok(NULL,DELIMITERS)) == NULL ) continue;
      strncpy(Problem[i].UniqueID,p,MAXUNIQUEID);       /* Pull off Node UniqueIDess */
      Problem[i].UniqueID[MAXUNIQUEID-1]='\0';          /* Null Terminate! */

      if ( (p=strtok(NULL,DELIMITERS)) == NULL ) continue;
      strncpy(Problem[i].TestName,p,MAXTESTNAME); /* Pull off Node UniqueIDess */
      Problem[i].TestName[MAXTESTNAME-1]='\0';    /* Null Terminate! */

      Error=FALSE;                              /* Pull off NetMgmtProtocols */
      Problem[i].StatusLine[0]='\0';
      while( (p=strtok(NULL,DELIMITERS)) != NULL)  {
         strncat(Problem[i].StatusLine,p,MAXSTATUSLINE-strlen(Problem[i].StatusLine));
         strncat(Problem[i].StatusLine," ",MAXSTATUSLINE-strlen(Problem[i].StatusLine));
      }
      Problem[i].StatusLine[MAXSTATUSLINE-1]='\0';

      i++;              /** Yea! We have a valid line **/
   }
   fclose(stream);
   Problem[i].Name[0]='\0';
   unlock(file);
   In_Critical_Section=0;
   return(i);
}

#define _1_GREATER_2 1
#define _1_LESSTHAN_2 -1

int CompareRoutine( p1, p2 )
struct ProblemType *p1,*p2;
{
	if (( p1->StatusLine[0] == '\0' ) && ( p2->StatusLine[0] != '\0' ))
		return( _1_LESSTHAN_2 );
	if (( p1->StatusLine[0] != '\0' ) && ( p2->StatusLine[0] == '\0' ))
		return( _1_GREATER_2 );

	/* BOTH ARE COMMENTED OR NOT COMMENTED - Sort by Time */
	return( p2->TimeStamp - p1->TimeStamp );
}

/*****************************************************************************
 * WriteProblemFile:  Write our problems to disk.                            *
 *****************************************************************************/
int WriteProblemFile(Problem,Problem_File,NumProblems)
struct ProblemType *Problem;
char *Problem_File;
int NumProblems;
{
FILE *stream;
int i;
char buffer[20];

   In_Critical_Section=1;
   if ( ! lock(Problem_File) )
	panic("WriteProblemFile: PROBLEM.FILE LOCKED ");

   if ((stream=fopen(Problem_File,"w"))==NULL) {
      perror("PROBLEM FILE NOT FOUND! Error.");
      exit(1);
   }

   qsort( Problem, NumProblems, sizeof(struct ProblemType), CompareRoutine );

   for(i=0; i<NumProblems; i++) {
      if (Problem[i].Name[0]!='\0')
         	fprintf(stream,"%s %s %s %s %s\n",
                ltoa(Problem[i].TimeStamp,buffer),Problem[i].Name,
                Problem[i].UniqueID,Problem[i].TestName,Problem[i].StatusLine);
   }
   fclose(stream);
   unlock(Problem_File);
   In_Critical_Section=0;
}

