/* test the top_three functionality
 * will print in the cmdline every second a list of
 * three best processes 
 */

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <dirent.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include <math.h>
#include <limits.h>
#include <errno.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <regex.h>
#include "gkrelltop.h"
#include <sys/time.h> //gettimeofday


#define SLEEPLENGTH 700000

void onexit_cleanup(void);

void onexit(int sig)
{
  perror("\nAttempting to cleanup\n");
  onexit_cleanup();
  exit(0);
}

int  show_nice_processes;
extern int pluginMode;

struct process *best[3] = { 0, 0, 0 };

int main (int argc, char ** argv)
{
  int n = 0;
  int i;
  char str [256];

  if(argc > 1) {
      if(strncmp(argv[1], "mem", 2) == 0)
          pluginMode = mem;
      else if(strncmp(argv[1], "io", 2) == 0)
          pluginMode = io;
  }


  /* catch when user presses ctrl-c SIGINT and perform cleanup */
  if(signal(SIGINT, onexit) == SIG_ERR) {
      perror("\nSignal not divertible; no cleanup upon exit\n");
  }

  show_nice_processes = 1;
  printf("start of the program, show_nice_processes=%d (%p)\n", 
          show_nice_processes, &show_nice_processes);

  int u_secs1 = 0; 
  int u_secs2 = 0;

  while (1)    //sorry
  { 
    /*
     * Find the top three!
     */

    //find the delays of the times, and see which method is better, 
    //if needed, call multiple times in a loop

    int i;
    struct timeval start;
    gettimeofday(&start, 0);

    //for(i=0;i<20;i++) {
    best[0] = best[1] = best[2] = NULL; //freeing occurrs in top_three.c
    n = gkrelltop_process_find_top_three(best);
    //}

    struct timeval end;
    gettimeofday(&end, 0);
    u_secs1 += (end.tv_sec - start.tv_sec) * 1000000 +
              (end.tv_usec - start.tv_usec);

    start = end;

    //for(i=0;i<20;i++) {
    best[0] = best[1] = best[2] = NULL; //freeing occurrs in top_three.c
    n = working_gkrelltop_process_find_top_three(best);
    //}

    gettimeofday(&end, 0);
    u_secs2 += (end.tv_sec - start.tv_sec) * 1000000 +
              (end.tv_usec - start.tv_usec);

    printf("u_secs1 = %d   u_secs2 = %d\n", u_secs1, u_secs2);

    if (n > 3) {
        /* cant have more than 3, some error occured */
        return 0;
    }

    if(n > 0) {
        printf("N(%d): ", n);

        for (i = 0; i < n; i++) {
            if(pluginMode == cpu)
                snprintf(str, sizeof(str), "[%-5.10s(%4.2f%c %5d)]", 
                        best[i]->name, best[i]->amount, '%', best[i]->pid);
            else if(pluginMode == mem)
                snprintf(str, sizeof(str), "[%-5.10s(%.2f%c %dM %5d)]", 
                        best[i]->name, best[i]->amount, '%', 
                        best[i]->rss/MEG, best[i]->pid);
            else if(pluginMode == io)
                snprintf(str, sizeof(str), "[%-5.10s(%.0f %.0fK %.0fK %5d)]", 
                    best[i]->name, best[i]->amount, 
                    (float)(best[i]->io_read - best[i]->previous_io_read)/KIL,
                    (float)(best[i]->io_write - best[i]->previous_io_write)/KIL,
                    best[i]->pid);

            printf("%s  ",str);
        }

        for(; i < 3; i++) {
          if (best[i]) {
            printf("WARNING: SHOULD NEVER GET HERE!!\n");
            snprintf(str, sizeof(str), "%d - %-10.10s(%c %.2f %5d)", i+1, 
                    best[i]->name,'%',best[i]->amount,best[i]->pid);
            printf("%s\t",str);
          }
        }

        printf("\n"); //15 CR, 12 linefeed
    }

    usleep(SLEEPLENGTH); /* microsleep in microseeconds */
  }

  return 0;
}
