/****************************************************************************/
/* Copyright (c) 2000 MBARI                                                 */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
/* Summary  :                                                               */
/* Filename : _fuelCellTest.cc                                              */
/* Author   : John Rieffel                                                  */
/* Project  :                                                               */
/* Version  : 1.0                                                           */
/* Created  : 02/07/2000                                                    */
/* Modified :                                                               */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <process.h>
#include <signal.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>

#include "mvc_fcc_api.h"
#include "EventService.h"
#include "FuelCellIF.h"
#include "FuelCellServer.h"
#include "Syslog.h"
#include "Task.h"
#include "System.h"

extern "C"{
Boolean debug_flag=FALSE;       // enable debug statements 
nid_t target_node;   
char *ProgramName;    
};

class FuelCellTest : public Task {

public:
  FuelCellTest(int argc, char **argv);
  virtual ~FuelCellTest();
  virtual void run();
  void event_catch(TaskInterface *taskInterface, EventCode code);

protected:
  FuelCellIF::FCC_data fcc_data;
  FuelCellIF::FCC_status fcc_status;
  FuelCellIF *fuelcell;
  pid_t _fuelCellServer;
  EventService *_eventService;
  

};

FuelCellTest::FuelCellTest(int argc, char **argv)
  :Task("FuelCellTest")
{
  _eventService   = new EventService("eventService", this);
  
  if ((_fuelCellServer = System::spawn("fuelCellServer","")) == -1)
    {
      Syslog::write("System::spawm(fuelCellSErver) failed\n");
    }
  try
    {
      fuelcell = new FuelCellIF("fuelcell");
    }
  
  catch (Exception e) {
    Syslog::write("fuelCellTest - caught Exception: %s", e.msg);
    exit(1);
  }
  catch (...) {
    Syslog::write("fuelCellTest - caught unknown exception");
    exit(1);
  }
  

}

FuelCellTest::~FuelCellTest()
{
  delete fuelcell;
  kill (_fuelCellServer, SIGTERM);
}



void FuelCellTest::event_catch(TaskInterface *taskinterface, EventCode code)
{
  // don't do much for now
  Syslog::write("caught event!\n");
}


void FuelCellTest::run()
{
  char buf[256];

  
  while (True)
    {

  //get status
  if(fuelcell->get_status(&fcc_status) != DeviceIF::Ok)
    fprintf(stdout, "Error from fuelcell->getstatus\n");
  else
    {
      //print some status


	printf("control status: %d, health: %x, fc remaining kwh: %d, bat remaining wh: %d, bit status: %d, bit_result: %d \n", 
	fcc_status.fc_control_state,
	fcc_status.health,
	fcc_status.FC_remaining_kwh,
	fcc_status.RB_remaining_wh,
	fcc_status.BIT_status,
	fcc_status.BIT_result);
	   
	}
 
      printf("Fuel Cell Test Program\n enter a command:\n");
      printf("d -- get (d)ata\n");
      printf("s -- get (s)tatus\n");
      printf("t -- s(t)art fuel cell\n");
      printf("p -- sto(p) fuel cell\n");
      printf("o -- (o)ffline\n");
      printf("r -- (r)esume\n");
      
      gets(buf);
      char *token = strtok(buf, " \t");
      if (!token)
	continue;
      if (!strcmp(token, "d"))
	{
	  // get data
	  if(fuelcell->get_data(&fcc_data) != DeviceIF::Ok)
	    fprintf(stdout, "Error from fuelcell->getData()\n");
	  else
	    {
	      //print some data
	      printf("data:\n\
			elapsed time:            %d\n\
		        anolyte pump a current:  %d\n\
			anolyte pump b current:  %d\n\
			catholyte pump current:  %d\n\
			peroxide pump current:   %d\n\
			anolyte temperature:     %d\n\
			catholyte temperature:   %d\n\
			forward peroxide temp:   %d\n\
			aft peroxide temp:       %d\n\
			stack voltage:           %d\n\
			stack current:           %d\n\
			battery voltage:         %d\n\
			battery current:         %d\n\
			peroxide used:           %d\n\
                        v_setpoint:              %d\n\
                        makeup injection count:  %d\n\
                        base injection duration: %d\n", 
		     fcc_data.elapsed_time,
		     fcc_data.anolyte_pump_a_current,
		     fcc_data.anolyte_pump_b_current,
		     fcc_data.catholyte_pump_current,
		     fcc_data.peroxide_pump_current,
		     fcc_data.anolyte_temp,
		     fcc_data.catholyte_temp,
		     fcc_data.fwd_peroxide_temp,
		     fcc_data.aft_peroxide_temp,
		     fcc_data.stack_voltage,
		     fcc_data.stack_current,
		     fcc_data.battery_voltage,
		     fcc_data.battery_current,
		     fcc_data.peroxide_used,
		     fcc_data.v_setpoint,
		     fcc_data.makeup_injection_count,
		     fcc_data.base_injection_duration
		     );
		              

	    }
	}
      else if (!strcmp(token, "s"))
	{
	  //get status
	  if(fuelcell->get_status(&fcc_status) != DeviceIF::Ok)
	    fprintf(stdout, "Error from fuelcell->getstatus\n");
	  else
	    {
	      //print some status
	      printf("control status: %d, health: %x, fc remaining kwh: %d, bat remaining wh: %d, bit status: %d, bit_result: %d \n", 
		     fcc_status.fc_control_state,
		     fcc_status.health,
		     fcc_status.FC_remaining_kwh,
		     fcc_status.RB_remaining_wh,
		     fcc_status.BIT_status,
		     fcc_status.BIT_result);
	    }
	}
      else if (!strcmp(token, "t"))
	{
	  Syslog::write("FuelCellTest: start command recieved\n");
	  //start
	  if (fuelcell->start() != DeviceIF::Ok)
	    fprintf(stdout, "Error in fuelcell->start()\n");
	  else
	    {
	    }
	}
      else if (!strcmp(token, "p"))
	{
	  Syslog::write("FuelCellTest: stop command recieved\n");
	  //stop
	  
	  // this should now be handled by the Server
	  // i.e. if FCC is in inappropriate control state
	  // command is not sent
	  
	  // if (fuelcell->offline() != DeviceIF::Ok)
	  //	fprintf(stdout, "Error in fuelcell->offline in fuelcell stop()\n");
	  
	  if (fuelcell->stop() != DeviceIF::Ok)
	    fprintf(stdout, "Error in fuelcell->stop()\n");
	  else
	    {
	    }
	}
      else if (!strcmp(token, "o"))
	{
	  Syslog::write("FuelCellTest: offline command recieved\n");
	  //offline
	  if (fuelcell->offline() != DeviceIF::Ok)
	    fprintf(stdout, "Error in fuelcell->offline()\n");
	  else
	    {
	    }
	}
      else if (!strcmp(token, "r"))
	{
	  Syslog::write("FuelCellTest: resume command recieved\n");
	  //resume
	  if (fuelcell->resume() != DeviceIF::Ok)
	    fprintf(stdout, "Error in fuelcell->resume()\n");
	  else
	    {
	    }
	}
      
      
    }
}


int main (int argc, char **argv)
{
  Boolean error = False;
  Boolean debug = True;
  FuelCellTest *test = 0;
  
  target_node = 11;
  
  ProgramName = argv[0];
  
  
  try{
    test = new FuelCellTest(argc, argv);
    test->run();
  }
  catch (Exception e) {
    fprintf(stderr, "Caught exception: %s\n", e.msg);
    error = True;
  }
  catch (...) {
    fprintf(stderr, "Caught some exception...");
    error = True;
  }
  dprintf("deleting test\n");
  delete test;
  dprintf("Kill child processes....");
  kill(0, SIGTERM);
  
  if (error)
       return 1;
  else
    return 0;
}
