# include "opihi.h"
# include "scheduler.h"

static char dot[] = ".";

static Task *tasks;
static int   Ntasks;
static int   NTASKS;

static char *TaskName = dot;

static int   CurrentTask = 0;

/* provide a mechanism to loop over the list of tasks */
Task *NextTask () {
  
  Task *task;

  if (CurrentTask >= Ntasks) {
    CurrentTask = 0;
    return (NULL);
  }

  task = &tasks[CurrentTask];
  CurrentTask ++;
  return (task);
}

void InitTasks () {
  NTASKS = 20;
  Ntasks = 0;
  ALLOCATE (tasks, Task, NTASKS);
  TaskName = dot;
}

/* list known tasks */
void ListTasks () {

  int i;

  for (i = 0; i < Ntasks; i++) {
    fprintf (stderr, "%-15s %20s\n", tasks[i].name, tasks[i].argv[0]);
  }
  return;
}

/* show details of a task */
int ShowTask (char *name) {

  int i;
  Task *task;

  task = FindTask (name);
  if (task == NULL) {
    fprintf (stderr, "task %s not found\n", name);
    return (FALSE);
  }

  fprintf (stderr, "macro %s\n", task[0].name);

  fprintf (stderr, "command: ");
  for (i = 0; i < task[0].argc; i++) {
    fprintf (stderr, "%s ", task[0].argv[i]);
  }

  fprintf (stderr, "host: %s\n", task[0].host);
  fprintf (stderr, "time periods: exec: %f  poll: %f  timeout: %f\n", 
	   task[0].exec_period, task[0].poll_period, task[0].timeout_period);

  fprintf (stderr, "pre-execute macro\n");
  ListMacro (task[0].exec);

  fprintf (stderr, "timeout macro\n");
  ListMacro (task[0].timeout);

  fprintf (stderr, "crash macro\n");
  ListMacro (task[0].crash);

  fprintf (stderr, "default exit macro\n");
  ListMacro (task[0].def);

  for (i = 0; i < task[0].Nexit; i++) {
    fprintf (stderr, "exit macro (status == %d)\n", atoi(task[0].exit[i][0].name));
    ListMacro (task[0].exit[i]);
  }

  return (TRUE);
}

/* return task with given name */
Task *FindTask (char *name) {

  int i;

  /* try for an exact match first */
  for (i = 0; i < Ntasks; i++) {
    if (!strcmp (tasks[i].name, name)) {
      return (&tasks[i]);
    }
  }
  return (NULL);
}  

/* make a new named task */
Task *CreateTask (char *name) {
  
  tasks[Ntasks].name = strcreate (name);;

  tasks[Ntasks].host = NULL;

  tasks[Ntasks].argc = 0;
  tasks[Ntasks].argv = NULL;

  tasks[Ntasks].exec = NULL;
  tasks[Ntasks].crash = NULL;
  tasks[Ntasks].timeout = NULL;

  tasks[Ntasks].Nexit = 0;
  tasks[Ntasks].NEXIT = 10;
  ALLOCATE (tasks[Ntasks].exit, Macro *, tasks[Ntasks].NEXIT);
  /* don't free tasks[0].exit, keep at least 1 allocated */

  tasks[Ntasks].exec_period = 1.0;
  tasks[Ntasks].poll_period = 1.0;
  tasks[Ntasks].timeout_period = 1.0;

  Ntasks ++;
  if (Ntasks == NTASKS) {
    NTASKS += 20;
    REALLOCATE (tasks, Task, NTASKS);
  }
  return (&tasks[Ntasks-1]);
}

void SetCurrentTask (char *name) {
  TaskName = name;
}

char *GetCurrentTask () {
  return (TaskName);
}

