#include <process.h>
#include "SmartSamplerServer.hh"
#include "ssdbg.hh"

/*
 * class SmartSamplerServer
 */
// structors:

SmartSamplerServer::SmartSamplerServer(const char *name)
  :shared_mem_rd(SharedData::Read),cmd_queue_wr(MessageQueue::Write)
{
  driver_name = strdup(name);
}

SmartSamplerServer::~SmartSamplerServer() {
  ssdbg(DBG_CLEAN)("destroying SmartSamplerServer");
  free((void *)driver_name);
}

// Manipulators :

// Interface methods defined in SmartSamplerIF_SK
void SmartSamplerServer::dtSuspend(short suspendNum){
  SmartSamplerInput::Command cmdObj(SmartSamplerInput::cmdSuspend, suspendNum);
  cmd_queue_wr.write(&cmdObj);
}

void SmartSamplerServer::dtResume(short resumeNum){
  SmartSamplerInput::Command cmdObj(SmartSamplerInput::cmdResume, resumeNum);
  cmd_queue_wr.write(&cmdObj);
}

void SmartSamplerServer::dtReset(short resetNum){
  SmartSamplerInput::Command cmdObj(SmartSamplerInput::cmdReset, resetNum);
  cmd_queue_wr.write(&cmdObj);
}

void SmartSamplerServer::dtNum(short *numDTs){
  shared_mem_rd.read();
  *numDTs = shared_mem_rd.data.dtNum;
}

void SmartSamplerServer::dtDumpState(){
  SmartSamplerInput::Command cmdObj(SmartSamplerInput::cmdDumpDTState);
  cmd_queue_wr.write(&cmdObj);
}

void SmartSamplerServer::dtDumpState(short dumpNum){
  SmartSamplerInput::Command cmdObj(SmartSamplerInput::cmdDumpDTState, dumpNum);
  cmd_queue_wr.write(&cmdObj);
}

void SmartSamplerServer::gulperState(SmartSamplerIF::GulperInfoArrayType gulperInfo){
  ssdbg(DBG_CMD)("SmartSamplerServer -- Reading gulper state.");
  shared_mem_rd.read();
  ssdbg(DBG_CMD)("SmartSamplerServer -- Copying memory."); 
  memcpy((void *)gulperInfo, (void *)&shared_mem_rd.data.gulperInfo,
	 sizeof(SmartSamplerIF::GulperInfoArrayType));
}

void SmartSamplerServer::gulperAllocate(short gulperNum,short dtNum){
  SmartSamplerInput::Command cmdObj(SmartSamplerInput::cmdAllocate, gulperNum, dtNum);
  cmd_queue_wr.write(&cmdObj);
}

void SmartSamplerServer::gulperFire(short gulperNum){
  SmartSamplerInput::Command cmdObj(SmartSamplerInput::cmdFire, gulperNum);
  cmd_queue_wr.write(&cmdObj);
}

void SmartSamplerServer::gulperLastFired(double *gulperTime, short *gulperNum){
  SmartSamplerIF::PerGulperInfo *ginfo;
  double curMax;
  int j,maxidx;
  
  ssdbg(DBG_CMD)("SmartSamplerServer -- Reading gulper state.");
  shared_mem_rd.read();
  curMax = -1;
  maxidx = -1;
  ssdbg(DBG_CMD)("SmartSamplerServer -- Finding last fired.");
  for(j=0; j<NGULPERS; j++){
    ginfo = &shared_mem_rd.data.gulperInfo[j];
    if((ginfo->curstate == SmartSamplerIF::Fired) &&
       (curMax < ginfo->time)){
      curMax = ginfo->time;
      maxidx = j;
    }
  }
  if(maxidx == -1){
    *gulperTime = -1;
    *gulperNum = -1;
  }else{
    *gulperTime = shared_mem_rd.data.gulperInfo[maxidx].time;
    *gulperNum = maxidx;
  }
}

int SmartSamplerServer::spawnAuxTasks() {
  char *program = (char *)driver_name;

  char errorBuf[256];
  char buf[256];
 
  pid_t pid;
 
  switch ((pid = fork())) {
     
  case 0:
    // In child
    // Execute driver program
    execlp(program, program, "", 0, 0);

    sprintf(errorBuf, 
	    "Task::spawnServer() - execlp() of \"%s\" failed", program);

    perror(errorBuf);
 
    break;

  case -1:
    perror("Task::spawnServer() - fork() failed");
    return -1;
  }

  return 0;
  
}


// 
