/* **********************************************************************
 * *                                                                    *
 * *               Antenna Position Logging Program                     *
 * *                                                                    *
 * **********************************************************************
 * File: utils/antenna/AntLog.C
 *
 *                        COPYRIGHT (c) 2004 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 <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "sigtypes.h"

#include "antenna_lib.h"
#include "user_lib.h"

struct command_line {		/* Original command line args */
  UINT4 iWaitTimeMicroSec; 	/*   Wait time in microseconds */
  UINT4 iSyncTimeMicroSec; 	/*   Sync time in microseconds */
  UINT1 lLogToFile ;		/*   Logging options */
  UINT1 lLogToTerm ;
  UINT1 lVerbose ;		/*   Log more details */
  UINT1 lAppendToLog ;		/*   Append to previous log file */
  UINT1 lDaemon;                /*   Run in daemon mode */
  FILE *iLogFile ;		/*   Open file descriptor to log file */
} ;

/* ------------------------------
 * Local function prototypes
 */

static void ProcessCommandLine
( int iArgc_a, char *sArgv_a[],
  struct command_line *pCmd_a ) ;

static void Usage( void ) ;

static MESSAGE SignalHandler
( MESSAGE iStatus_a, UINT4 iCount_a, const UINT4 iSigArgs_a[] ) ;

void Lprintf
( const struct command_line *pCmd_a, const char *sString_a ) ;

/* ------------------------------
 * Shared variables
 */
static struct command_line Command_c ;

/* ********************
 * *                  *
 * *  Top Level MAIN  *
 * *                  *
 * ********************
 */
int main( int iArgc_a, char** sArgv_a )
{
  MESSAGE iStatus;
  setlocale( LC_ALL, "" ) ;
  UINT1 lFirst;

  /* Process the command line arguments
   */
  ProcessCommandLine( iArgc_a, sArgv_a, &Command_c ) ;

  if (Command_c.lDaemon) sig_daemon_init();

  /* Open the logging file, if any.  Starting from here we can use the
   * Lprintf function.
   */
  if (Command_c.lLogToFile) {
    char *sptr ;
    char sLogPath[PATHNAME_SIZE] ;
    sptr = getenv( "IRIS_LOG" ) ;
    if (sptr)
      {
	strncpy( sLogPath, sptr, PATHNAME_SIZE-20 ) ;
	sLogPath[PATHNAME_SIZE-20] = 0 ;
      }
    else
      strcpy( sLogPath, "/tmp/" ) ;
    strcat( sLogPath, "AntLog.log" ) ;
    if (Command_c.lAppendToLog)
      Command_c.iLogFile = fopen( sLogPath, "a" ) ;
    else
      Command_c.iLogFile = fopen( sLogPath, "w" ) ;
    if (NULL == Command_c.iLogFile)
      {
	fprintf( stderr, "Can not open log file: '%s'\n", sLogPath ) ;
	exit(EXIT_FAILURE) ;
      }
    }
  /* Print out welcome messages */
  Lprintf( &Command_c, "Antenna Logging Utility Started.\n") ;
  //  if (Command_c.lVerbose) Lprintf( &Command_c, "Verbose Logging On.\n") ;

  /* Setup the signal handler.  This handler uses Lprintf(), so wait
   * till here to set it up.
   */
  sig_establish( SignalHandler, "AntLog" ) ;

  /* Open the antenna driver
   */
  iStatus = AntPowerUpMain( ANT_IAM_CLIENT, 0 ) ;
  if( iStatus != SS_NORMAL )
    {
      sig_signal( iStatus ) ; exit(EXIT_FAILURE) ;
    }

  Lprintf( &Command_c, "PktAge;   -Az-   -El-    Age;   Head   Roll  Pitch    Age\n") ;
  /* Loop forever, reading the antenna position and logging it,
   * As long as the antenna library is still running.
   */
  lFirst=TRUE;
  while(!lAntLibShutDown())
    {
      UINT4 iAgePkt, iAgePos, iAgeShip, iBtimeNow;
      struct rtship Rtship;
      struct rtpedx Rtpedx;
      char sLog[160];
      getbtime( &iBtimeNow ) ; 
      AntGetAges( &iAgePkt, &iAgePos, &iAgeShip );
      /* Limit age number to prevent line lengthening */
      if (iAgePkt>99999)  iAgePkt=99999;
      if (iAgePos>99999)  iAgePos=99999;
      if (iAgeShip>99999) iAgeShip=99999;
      ant_get_rtpedx( &Rtpedx, iBtimeNow );
      ant_get_rtship( &Rtship, iBtimeNow ) ;

      sprintf( sLog, "%6.3f; %6.2f %6.2f %6.3f; %6.2f %6.2f %6.2f %6.3f\n",
	       ((FLT4)iAgePkt)/1000.0, Rtpedx.faz, Rtpedx.fel,((FLT4)iAgePos)/1000.0,
	       Rtship.fheading, Rtship.froll, Rtship.fpitch,((FLT4)iAgeShip)/1000.0 );
      Lprintf( &Command_c, sLog );
      if (lFirst && Command_c.iSyncTimeMicroSec )
	{
	  struct ymds_time Ymds;
	  SINT4 iMs, iRemainder, iWait;
	  GetTimeYmds( &Ymds, TIME_FLG_UTC );
	  iMs = (1000*Ymds.isec) + MS_FROM_MILLS( Ymds.imills );
	  iRemainder = iMs % (Command_c.iSyncTimeMicroSec/1000);
	  iWait = 4+(Command_c.iSyncTimeMicroSec/1000)-iRemainder;
	  sig_microSleep( Command_c.iWaitTimeMicroSec+(1000*iWait) ) ;
	}
      else
	{
	  sig_microSleep( Command_c.iWaitTimeMicroSec ) ;
	}
      lFirst=FALSE;
    }
  ant_close();
  Lprintf( &Command_c, "Antenna Logging Utility Stopped.\n") ;

}

/* ==============================================
 * Function to process the command line arguments.
 */
static void ProcessCommandLine
( int iArgc_a, char *sArgv_a[],
  struct command_line *pCmd_a )
{
  int iArg ; char *pEnd ;

  memset( pCmd_a, 0, sizeof(*pCmd_a) ) ;
  pCmd_a->iWaitTimeMicroSec = 1000000 ;
  pCmd_a->lLogToFile = TRUE;
  
  /* Parse command line options
   */
  for( iArg=1 ; iArg<iArgc_a ; iArg++ )
    {
      const char *sArg = sArgv_a[iArg] ;
      
      if( 0 == strncmp( sArg, "-daemon", 7 ) ) 
	{
	  pCmd_a->lDaemon = TRUE ;
	}
      else if (0 == strncmp( sArg, "-h", 2 ))
	{
	  Usage() ;
	}
      else if ( 0 == strncmp( sArg, "-log:", 5 ))
	{
	  if ( 0 == strcmp( "both", &sArg[5] ) ) 
	    {pCmd_a->lLogToFile=TRUE ;  pCmd_a->lLogToTerm=TRUE ;}
	  else if ( 0 == strcmp( "file", &sArg[5] ) ) 
	    {pCmd_a->lLogToFile=TRUE ;  pCmd_a->lLogToTerm=FALSE ;}
	  else if ( 0 == strcmp( "term", &sArg[5] ) )
	    {pCmd_a->lLogToFile=FALSE ; pCmd_a->lLogToTerm=TRUE ;}
	  else if ( 0 == strcmp( "none", &sArg[5] ) )
	    {pCmd_a->lLogToFile=FALSE ; pCmd_a->lLogToTerm=FALSE ;}
	}
      else if (0 == strncmp( sArg, "-sync:", 6 ))
	{
	  FLT8 fTime;
	  fTime = strtod( &sArg[6], &pEnd ) ;
	  if ( pEnd == &sArg[6] ) 
	    {
	      printf( "-sync syntax error.\n" ) ;
	      exit(EXIT_FAILURE) ;
	    }
	  if ((fTime<0.00) || (fTime>60.0))
	    {
	      printf( "Time must be in range 0 to 60 seconds.\n" ) ;
	      exit(EXIT_FAILURE) ;
	    }
	  pCmd_a->iSyncTimeMicroSec = NINT(1000000.0 * fTime);
	}
      else if (0 == strncmp( sArg, "-time:", 6 ))
	{
	  FLT8 fTime;
	  fTime = strtod( &sArg[6], &pEnd ) ;
	  if ( pEnd == &sArg[6] ) 
	    {
	      printf( "-time syntax error.\n" ) ;
	      exit(EXIT_FAILURE) ;
	    }
	  if ((fTime<.01) || (fTime>600.0))
	    {
	      printf( "Time must be in range 1/100 sec to 10 minutes.\n" ) ;
	      exit(EXIT_FAILURE) ;
	    }
	  pCmd_a->iWaitTimeMicroSec = NINT(1000000.0 * fTime);
	}
      else if (0 == strncmp( sArg, "-v", 3 ))
	{
	  pCmd_a->lVerbose = TRUE ;
	}
    }

  /* Do some cross checking */
  if (pCmd_a->lDaemon && pCmd_a->lLogToTerm)
    {
      fprintf( stderr, "Warning: -daemon flag overriding -log:term\n" ) ;
      pCmd_a->lLogToTerm=FALSE;
    }

}

/* ------------------------------
 * Print command line usage
 */
static void Usage( void )
{
  fprintf( stderr, "AntLog options:\n" ) ;
  fprintf( stderr, "  -daemon        -- Run as daemon\n" ) ;
  fprintf( stderr, "  -help          -- Print this list\n" ) ;
  fprintf( stderr, "  -log:<option>  -- Log options: term, file, both, none\n" ) ;
  fprintf( stderr, "  -sync:<number> -- Time in seconds to sync logs (default 0.0)\n" ) ;
  fprintf( stderr, "  -time:<number> -- Time in seconds between logs (default 1.0)\n" ) ;
  //  fprintf( stderr, "  -v             -- Verbose logging\n" ) ;
  fprintf( stderr, "   (all other arguments ignored)\n" ) ;
  exit(EXIT_FAILURE) ;
}

/* ************************************
 * *                                  *
 * *  Exception Handlers and Logging  *
 * *                                  *
 * ************************************
 */
/* ------------------------------
 * Function to print signaled errors to the logging file or terminal.
 */
static MESSAGE SignalHandler
( MESSAGE iStatus_a,
  UINT4 iCount_a,
  const UINT4 iSigArgs_a[] )
{
  char sMessage[170] ;

  strncpy( sMessage, message_to_text( iStatus_a, iCount_a, iSigArgs_a ), 165 ) ;
  sMessage[165]=0 ;
  strcat( sMessage, "\n" ) ;

  Lprintf( &Command_c, sMessage ) ;
  return( SS_NORMAL ) ;
}

/* ------------------------------
 * Print string to log and terminal, if desired.
 */
void Lprintf
( const struct command_line *pCmd_a,
  const char *sString_a )
{
  struct full_time_spec Time;
  SINT4 iMs;
  char sFullTime[80], sTimeBuf[TIMENAME_SIZE], sDateBuf[TIMENAME_SIZE];
  GetTimeFull( &Time, TIME_FLG_LOCAL );
  iMs = MS_FROM_MILLS( Time.Ymds.imills );

  shhmmss_r( Time.Ymds.isec, sTimeBuf );
  sddmonyyyy_r( Time.Ymds.iyear, Time.Ymds.imon, Time.Ymds.iday, sDateBuf );
  sprintf( sFullTime, "%s.%03d %s %s:", sTimeBuf, iMs, sDateBuf, Time.sRecordTZName );

  if (pCmd_a->lLogToTerm) 
    {
      fputs( sFullTime, stderr ) ;
      fputs( sString_a, stderr ) ;
    }
  if (pCmd_a->lLogToFile)
    {
      fputs( sFullTime, pCmd_a->iLogFile ) ;
      fputs( sString_a, pCmd_a->iLogFile ) ;
      fflush( pCmd_a->iLogFile ) ;
    }
}

