/* **********************************************************************
 * *                                                                    *
 * *        Antenna Logging Process and Non-Realtime Services           *
 * *                                                                    *
 * **********************************************************************
 * File: libs/antenna/ant_log.c
 *
 *                        COPYRIGHT (c) 2005  BY
 *          SIGMET INCORPORATED, WESTFORD MASSACHUSETTS, U.S.A.
 * 
 * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
 * ONLY  IN  ACCORDANCE WITH  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE
 * INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE  OR  ANY OTHER
 * COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
 * OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
 * TRANSFERED.
 */
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>

#define INCLUDE_STDIO_PROTOTYPES 1
#include "sigtypes.h"
#include "event_flags.h"
#include "user_lib.h"
#include "setup.h"
#include "antenna_lib.h"
#include "antenna_int.h"

#include "ant_global.h"

/* ------------------------------
 * This process is created during initial powerup of the antenna
 * library.  It's primary purpose is to handle error logging and
 * swapping of log files as needed.
 */
int main( int argc_a, char *argv_a[] )
{
  MESSAGE istatus ; struct ymds_time timeFile={0} ;
  char *sPtr, sLogDir[PATHNAME_SIZE] ; SINT4 ii, iFD = -1 ;

  /* Powerup the antenna library for this logging process.
   */
  setlocale( LC_ALL, "" ) ;

  istatus = sig_run_as_operator() ;
  if( istatus != SS_NORMAL ) sig_signal(istatus) ;

  istatus = AntPowerUpMain( ANT_IAM_LOGGER, 0 ) ;
  if ( istatus != SS_NORMAL ) {
    sig_signal( istatus ) ; exit(EXIT_FAILURE) ;
  }
  antGlobal_c->info.iLogStatus = istatus ;

  /* Setup the directory into which we'll be writting the log files.
   */
  sPtr = getenv( "IRIS_LOG" ) ;
  if( sPtr) {
    strncpy( sLogDir, sPtr, PATHNAME_SIZE-20 ) ;
    sLogDir[PATHNAME_SIZE-20] = 0 ;
  } else {
    strcpy( sLogDir, "/tmp/" ) ;
  }
  /* The logging process runs forever.  Wait to be awakened by anyone
   * writing into the shared memory log FIFO, then determine the file
   * to which we're writing/appending and copy the lines of text.
   */
  antWriteLog( "LOG Process Starting" ) ;
  for(;;) {
    struct ymds_time timeNow ; char sLogLine[ ANTLOGCOL_MAX ] ;

    sig_waitef( ANTENNA_LOGFILE_EF ) ;
    sig_clref ( ANTENNA_LOGFILE_EF ) ;

    /* Check whether we need to open a new file, either because we
     * have none open now, or because we've crossed a daily boundary.
     */
    GetTimeYmds( &timeNow, TIME_FLG_LOCAL ) ;

    if( ( iFD < 0 ) ||
	( timeNow.iyear != timeFile.iyear ) ||
	( timeNow.imon  != timeFile.imon  ) ||
	( timeNow.iday  != timeFile.iday  ) ) {

      /* We need to open a new file.  Make up the filename based on
       * the current time, close any old file, and try to open/create
       * the new file.
       */
      SINT4 iFlags = O_CREAT | O_RDWR  | O_APPEND ;
      SINT4 iMode  = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH ;
      char sLogPath[PATHNAME_SIZE], sFileName[40], sMonth[4]={0} ;

      timeFile = timeNow ;	/* Assign new file time */
      if( iFD >= 0 ) {		/* Close up any file presently open */
	ii = antFormatLogEntry( sLogLine,
	  "Log file ended because the daily midnight seam was reached", NULL ) ;
	write( iFD, sLogLine, ii ) ; close(iFD) ; iFD = -1 ;
      }
      memcpy( sMonth, sMonth3(timeFile.imon), 3 ) ; STR_LOWER( sMonth, 3 ) ;
      sprintf( sFileName, "antlib-%2.2d-%s-%4.4d.log",
	       timeFile.iday, sMonth, timeFile.iyear ) ;
      strcpy( sLogPath, sLogDir ) ; strcat( sLogPath, sFileName ) ;

      iFD = open( sLogPath, iFlags, iMode ) ;
      if( iFD < 0 ) sig_signal( errno_to_message( errno ) ) ;
      else {
	char sSymPath[PATHNAME_SIZE], sText[120], sTimeName[TIMENAME_SIZE] ;

	/* Make an entry into the logfile every time we open it anew.
	 * This helps find the seams where the antenna driver starts
	 * up and where there is probably a gap in time in the file.
	 */
	ii = antFormatLogEntry( sLogLine,
	  "================= Log Process File Seam =================", NULL ) ;
	write( iFD, sLogLine, ii ) ;
	sprintf( sText, "Opened %s on %s (Local Time)",
		 sFileName, shhmmssmmm_ddmonyyyy( &timeFile, sTimeName ) ) ;
	ii = antFormatLogEntry( sLogLine, sText, NULL ) ;
	write( iFD, sLogLine, ii ) ;

	/* Make a symbolic link to the most recent log file for the
	 * convenience of users wanting to manually access the current
	 * info under a simple name.
	 */
	strcpy( sSymPath, sLogDir ) ; strcat( sSymPath, "antlib.log" ) ;	
	unlink( sSymPath ) ; symlink( sFileName, sSymPath ) ;

	/* Remove old files, keeping only the requested number of the
	 * most recent ones.
	 */
	sprintf( sText, "cd %s ; ls -t1 | grep 'antlib-..-...-....\\.log' | "
		 "tail +%d | xargs rm -f",
		 sLogDir, (1 + antGlobal_c->setup.iLogDaysKept) ) ;
	system( sText ) ;
      }
    }
    /* Write queued log entries to the presently open logfile.
     */
    if( iFD >= 0 ) {
      UINT1 sChunk[ 200 ] ; SINT4 iChunk ;
      while( ( iChunk = bfifo_read_array
	       ( &antGlobal_c->vdat.LogFIFO, sChunk, sizeof(sChunk) ) ) > 0 ) {
	write( iFD, sChunk, iChunk ) ;
      }
    }
  }
  return(0) ;
}
