#include "license_pbs.h" /* See here for the software license */
/*
 *
 * qgpumode - Change GPU mode on a MOM
 *
 * Authors:
 *      Al Taufer
 *      Adaptive Computing
 */

#include "cmds.h"
#include "net_cache.h"
#include <pbs_config.h>   /* the master config generated by configure */
#include "../lib/Libifl/lib_ifl.h"

int exitstatus = 0; /* Exit Status */

static void execute(char *, char *, int, const char *);

/* qgpumode */

int main(

  int    argc,
  char **argv)

  {
  int   c;
  int   errflg = 0;
  char *gpuid = NULL;
  int   gpumode = -1;

  char *mom_node = NULL;

#define GETOPT_ARGS "H:g:m:"

  while ((c = getopt(argc, argv, GETOPT_ARGS)) != EOF)
    {
    switch (c)
      {

      case 'H':

        if (strlen(optarg) == 0)
          {
          fprintf(stderr, "qgpumode: illegal -H value\n");
          errflg++;
          break;
          }

        mom_node = optarg;

        break;

      case 'g':

        if (strlen(optarg) == 0)
          {
          fprintf(stderr, "qgpumode: illegal -g value\n");
          errflg++;
          break;
          }

        gpuid = optarg;

        break;

      case 'm':

        gpumode = atoi(optarg);
        
        if (gpumode < 0 || gpumode > 3)
          {
          fprintf(stderr, "qgpumode: illegal -m value\n");
          errflg++;
          }

        break;

      default:

        errflg++;

        break;
      }
    }    /* END while (c) */

  if (errflg || (mom_node == NULL) || (gpuid == NULL) || (gpumode == -1))
    {
    static char usage[] = "usage: qgpumode -H host -g gpuid -m mode\n";

    fprintf(stderr, "%s", usage);

    exit(2);
    }

  execute(mom_node, gpuid, gpumode, "");

  exit(exitstatus);

  /*NOTREACHED*/

  return(0);
  }  /* END main() */

/*
 * void execute( char *node, char *gpuid, int mode, const char *server )
 *
 * node     The name of the MOM node.
 * gpuid    The id of the GPU
 * mode     The num mode for the GPU
 * server   The name of the server to send to.
 *
 * Returns:
 *  None
 *
 * File Variables:
 *  exitstatus  Set to two if an error occurs.
 */
static void execute(
    
  char *node,
  char *gpuid,
  int   mode,
  const char *server)

  {
  int ct;         /* Connection to the server */
  int merr;       /* Error return from pbs_manager */
  int local_errno = 0;
  char *errmsg;   /* Error message from pbs_manager */

  /* The request to change mode */

  if ((ct = cnt2server(server)) > 0)
    {
    merr = pbs_gpumode_err(ct, node, gpuid, mode, &local_errno);

    if (merr != 0)
      {
      errmsg = pbs_geterrmsg(ct);

      if (errmsg != NULL)
        {
        fprintf(stderr, "qgpumode: %s ", errmsg);

        free(errmsg);
        }
      else
        {
        fprintf(stderr, "qgpumode: Error (%d - %s) changing GPU mode",
                local_errno,
                pbs_strerror(local_errno));
        }

      if (notNULL(server))
        fprintf(stderr, "@%s", server);

      fprintf(stderr, "\n");

      exitstatus = 2;
      }

    pbs_disconnect(ct);
    }
  else
    {
    local_errno = -1 * ct;

    fprintf(stderr, "qgpumode: could not connect to server %s (%d) %s\n",
            server,
            local_errno,
            pbs_strerror(local_errno));
    exitstatus = 2;
    }
  }
