# include "pcontrol.h"

// we use CheckPoints in this function to prevent objects in flight from being missing.
int host (int argc, char **argv) {

  int StackID;
  IDtype HostID;
  Host *host;

  if (argc != 3) goto usage;

  if (!strcasecmp (argv[1], "ADD")) {
    HostID = AddHost (argv[2]);
    gprint (GP_LOG, "HostID: %d\n", (int) HostID);
    return (TRUE);
  }
  if (!strcasecmp (argv[1], "ON")) {
    host = PullHostFromStackByName (PCONTROL_HOST_OFF, argv[2]);
    if (!host) {
      gprint (GP_LOG, "host %s is not OFF\n", argv[2]);
      return (FALSE);
    }
    host[0].markoff = FALSE;
    DownHost (host);
    return (TRUE);
  }
  if (!strcasecmp (argv[1], "RETRY")) {
    // no need to use a check point [thief: CheckDownHost (DOWN->IDLE)]
    host = PullHostFromStackByName (PCONTROL_HOST_DOWN, argv[2]);
    if (!host) {
      gprint (GP_LOG, "host %s is not DOWN\n", argv[2]);
      return (FALSE);
    }
    /* reset time, place back on DOWN stack */
    host[0].nexttry.tv_sec  = 0;
    host[0].nexttry.tv_usec = 0;
    host[0].lasttry.tv_sec  = 0;
    host[0].lasttry.tv_usec = 0;
    PutHost (host, PCONTROL_HOST_DOWN, STACK_BOTTOM);
    return (TRUE);
  }
  if (!strcasecmp (argv[1], "CHECK")) {
    SetCheckPoint ();  // ensure the host is on one of the stacks
    host = PullHostByName (argv[2], &StackID);
    if (host == NULL) {
      gprint (GP_LOG, "host %s not found\n", argv[2]);
      ClearCheckPoint ();
      return (FALSE);
    }
    PutHost (host, StackID, STACK_BOTTOM);
    ClearCheckPoint ();

    gprint (GP_LOG, "host %s is %s\n", argv[2], GetHostStackName (StackID));
    return (TRUE);
  }
  if (!strcasecmp (argv[1], "OFF")) {
    SetCheckPoint (); // ensure we can find the specified host
    host = PullHostByName (argv[2], &StackID);
    if (host == NULL) {
      gprint (GP_LOG, "host %s not found\n", argv[2]);
      ClearCheckPoint ();
      return (FALSE);
    }
    host[0].markoff = TRUE;
    PutHost (host, StackID, STACK_BOTTOM);
    ClearCheckPoint ();
    return (TRUE);
  }

  if (!strcasecmp (argv[1], "DELETE")) {
    // a check point is not required: no possible thief
    host = PullHostFromStackByName (PCONTROL_HOST_OFF, argv[2]);
    if (!host) {
      gprint (GP_LOG, "host %s is not OFF\n", argv[2]);
      return (FALSE);
    }
    DelHost (host);
    return (TRUE);
  }
  
usage:
  gprint (GP_LOG, "USAGE: host (command) (hostname)\n");
  gprint (GP_ERR, "  valid commands: add, on, retry, check, off, delete\n");
  return (FALSE);
}
