/****************************************************************************/
/* Copyright (c) 2000 MBARI                                                 */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
/* Summary  :                                                               */
/* Filename : System.cc                                                     */
/* Author   :                                                               */
/* Project  :                                                               */
/* Version  : 1.0                                                           */
/* Created  : 02/07/2000                                                    */
/* Modified :                                                               */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <process.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/sched.h>
#include <unistd.h>
#include "System.h"
#include "Syslog.h"
#include "Exception.h"

const char *System::configurationFile(const char *basename)
{
  static char filename[256];

  //////////////////////////////////////////////////////////////////
  // Build default file name
  char *auvConfigDir = getenv(AuvConfigDirName);

  if (auvConfigDir == 0) {

    Syslog::write("Environment variable %s not set\n",
		  AuvConfigDirName);

    auvConfigDir = "/usr/auv/dorado/config";

    Syslog::write("Using default directory %s", auvConfigDir);
  }

  sprintf(filename, "%s/%s", auvConfigDir, basename);

  return filename;
}


const char *System::missionPlanFile(const char *basename)
{
  static char filename[256];

  //////////////////////////////////////////////////////////////////
  // Build default file name
  char *planDir = getenv(AuvPlanDirName);

  if (planDir == 0) {

    Syslog::write("Environment variable %s not set\n",
		  AuvPlanDirName);

    planDir = "/usr/auv/dorado/config";

    Syslog::write("Using default directory %s", planDir);
  }

  sprintf(filename, "%s/%s", planDir, basename);

  return filename;
}


#define MaxExecArgs 15

pid_t System::spawn(const char *programName, const char *args)
{
  char errorBuf[256];

  char buf[512];
  strcpy(buf, args);

  // Parse argument string into argv array
  const char *argv[MaxExecArgs];

  int nArgs = 0;
  argv[nArgs++] = programName;
  char *ptr = buf;
  char *token;

  while ((token = strtok(ptr, " \t")) != 0) {
    ptr = 0;
    if (nArgs >= MaxExecArgs) {
      // Too many arguments
      Syslog::write("System::spawn() - %s %s - too many arguments\n",
		    programName, args);
      return -1;
    }

    argv[nArgs++] = token;
  }

  // Mark end of argument list
  argv[nArgs] = 0;

  pid_t pid;

  switch ((pid = fork())) {
    
  case 0:
    // In child
    // Execute server program
    execvp(programName, argv);

    sprintf(errorBuf, 
	    "System::spawn() - execlp() of \"%s\" failed", programName);

    perror(errorBuf);
    return -1;

    break;

  case -1:
    perror("System::spawn() - fork() failed");
    return -1;
  }

  return pid;
}

int System::setTaskPriority(int priority)
{
  // Set priority
  struct sched_param scheduleParams;
 
  scheduleParams.sched_priority = priority;
  if (sched_setparam(0, &scheduleParams) == -1) {
    Syslog::write("%s, sched_setparam() - %s", strerror(errno));
    return -1;
  }
  else
    return 0;
}  


void System::copyToLogDir(const char *filename)
{
  char errorBuf[256];

  //////////////////////////////////////////////////////////////////
  // Copy config file to log directory
  char *auvLogDir = getenv(AuvLogDirName);

  if (auvLogDir == 0) {

    sprintf(errorBuf, 
	    "System::copyToLogDir() - environment variable %s not set\n",
	    AuvLogDirName);

    throw Exception(errorBuf);
  }

  char cmd[256];

  sprintf(cmd, "cp %s %s/%s/.", filename, auvLogDir, LatestLogDirName);
  if (system(cmd) != 0) {
    sprintf(errorBuf, "System::copyToLogDir() - \"%s\" failed", cmd);
    throw Exception(errorBuf);
  }
}

void System::milliSleep( unsigned long millisecs )
{
     Boolean debug = False;
     struct timespec sleepTime;

     if( millisecs > 1000 ) {
	  sleepTime.tv_sec = millisecs / 1000;
	  millisecs -= 1000 * (millisecs / 1000);
     } else {
	  sleepTime.tv_sec = 0;
     }
     sleepTime.tv_nsec = millisecs * 1000000;

     dprintf("System::milliSleep -- Sleeping for %lu secs and %lu nsec",
	     sleepTime.tv_sec, sleepTime.tv_nsec );

     nanosleep( &sleepTime, NULL );
}

