# include "pcontrol.h"

int KillJob (Job *job, Host *host) {
  
  IOBuffer buffer;
  int status;
  char *p;

  ASSERT (host != NULL, "host missing");
  ASSERT (job != NULL, "job missing");

  ASSERT (host == (Host *) job[0].host, "invalid host");
  ASSERT (job  == (Job *) host[0].job, "invalid job");

  InitIOBuffer (&buffer, 0x100);

  status = PclientCommand (host, "reset", PCLIENT_PROMPT, &buffer);

  /* check on success of pclient command */
  switch (status) {
    case PCLIENT_DOWN:
      HarvestHost (host[0].pid);
      // unlink host & job
      job[0].host = NULL;
      host[0].job = NULL;
      PutHost (host, PCONTROL_HOST_DOWN, STACK_BOTTOM);
      PutJob (job, PCONTROL_JOB_CRASH, STACK_BOTTOM);
      FreeIOBuffer (&buffer);
      return (FALSE);

    case PCLIENT_HUNG:
      // don't do anything drastic, just keep trying
      // XXX move to which stack??
      gprint (GP_ERR, "client is busy, not responding (KillJob)");
      FreeIOBuffer (&buffer);
      return (TRUE);

    case PCLIENT_GOOD:
      if (VerboseMode()) gprint (GP_ERR, "message received (KillJob)\n");  
      break;

    default:
      ABORT ("unknown status for pclient command");  
  }

  /** host is up, need to parse message **/
  p = memstr (buffer.buffer, "STATUS", buffer.Nbuffer);
  ASSERT (p != NULL, "missing STATUS in pclient message");
  if (VerboseMode()) gprint (GP_ERR, "client message: %s\n", buffer.buffer);

  sscanf (p, "%*s %d", &status);
  FreeIOBuffer (&buffer);
  gprint (GP_ERR, "client status: %d\n", status);

  switch (status) {
    case -1:
      ABORT ("syntax error to pclient");
    case 0:
      gprint (GP_ERR, "failure to kill child process\n");
      PutHost (host, PCONTROL_HOST_BUSY, STACK_BOTTOM);
      PutJob (job, PCONTROL_JOB_KILL, STACK_BOTTOM);
      return (FALSE);
    case 1:
      gprint (GP_ERR, "killing job %s on %s\n", job[0].argv[0], host[0].hostname);
      // unlink host & job
      job[0].host = NULL;
      host[0].job = NULL;
      PutHost (host, PCONTROL_HOST_IDLE, STACK_BOTTOM);
      PutJob (job, PCONTROL_JOB_CRASH, STACK_BOTTOM);
      return (TRUE);
    case 2:
      ABORT ("client has no job");
  }
  ABORT ("should not reach here (KillJob)");
}
