/*
 * Copyright 2015 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <fcntl.h>
#include <getopt.h>
#include <glob.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <unistd.h>

#define DEFAULT_READ_INTERVAL 60
#define DEFAULT_PROCS_TO_SAMPLE 5
#define DEFAULT_WARMUP_SECONDS 600

#define DEFAULT_PROC_GLOB_PATH "/proc/[0-9]*/stat"

#define CMD_LEN 15
#define STR(X) #X
#define XSTR(X) STR(X)

struct proc {
  pid_t pid;
  char cmd[CMD_LEN + 1];
  unsigned long msec;
};

struct proc_list {
  struct proc *procs;
  int count;
};

static long ticks_per_sec;

void die(const char *msg)
{
  fprintf(stderr, "error: %s\n", msg);
  exit(1);
}

unsigned long ticks_to_ms(unsigned long ticks)
{
  return (1000.0 / ticks_per_sec) * ticks;
}

void read_stat(struct proc *proc, const char *stat_path)
{
  char buf[256];
  int pid_int;
  unsigned long utime;
  unsigned long stime;
  int rc;
  int fd;

  fd = open(stat_path, O_RDONLY);
  /* This isn't an error. We have a list of files which existed the moment the
     glob was run. If a process exits before we get around to reading it, its
     /proc files will go away. */
  if (fd == -1)
    return;

  rc = read(fd, buf, sizeof(buf) - 1);
  if (rc < 1)
    die("read");
  close(fd);
  buf[rc] = '\0';

  rc = sscanf(buf,
      "%d (%" XSTR(CMD_LEN) "[^)]) %*c %*d %*d %*d %*d %*d %*u %*u "
      "%*u %*u %*u %lu %lu", &pid_int, proc->cmd, &utime, &stime);
  if (rc != 4)
    die("sscanf");

  proc->pid = pid_int;
  proc->msec = ticks_to_ms(utime + stime);
}

int proc_pid_cmp(const void *a, const void *b)
{
  const struct proc *_a = a;
  const struct proc *_b = b;
  return _a->pid - _b->pid;
}

int proc_msec_cmp(const void *a, const void *b)
{
  const struct proc *_a = a;
  const struct proc *_b = b;
  return _a->msec - _b->msec;
}

void print_top(struct proc_list *new_procs, struct proc_list *old_procs,
    int procs_to_sample, int interval)
{
  struct proc top[new_procs->count];
  int top_count;
  int i, lim;

  top_count = 0;
  for (i = 0; i < new_procs->count; i++) {
    struct proc *new_proc = &new_procs->procs[i];
    struct proc *old_proc = bsearch(new_proc, old_procs->procs, old_procs->count,
        sizeof(*old_procs->procs), proc_pid_cmp);
    if (old_proc) {
      top[top_count] = *new_proc;
      top[top_count].msec = new_proc->msec - old_proc->msec;
      top_count++;
    }
  }

  qsort(top, top_count, sizeof(*top), proc_msec_cmp);

  printf("%dsec:", interval);
  lim = (top_count > procs_to_sample) ? (top_count - procs_to_sample) : 0;
  for (i = top_count - 1; i >= lim; i--) {
    printf(" %s(%.3f)", top[i].cmd, top[i].msec / 1000.0);
  }
  printf("\n");
}

void read_procs(struct proc_list *new_procs, const char *proc_glob_path)
{
  glob_t pglob;
  unsigned i;
  int rc;

  rc = glob(proc_glob_path, GLOB_NOSORT, NULL, &pglob);
  if (rc != 0)
    die("glob");

  new_procs->count = pglob.gl_pathc;
  new_procs->procs = malloc(new_procs->count * sizeof(*new_procs->procs));
  if (!new_procs->procs)
    die("out of memory");

  for (i = 0; i < pglob.gl_pathc; i++) {
    read_stat(&new_procs->procs[i], pglob.gl_pathv[i]);
  }

  globfree(&pglob);

  /* glob sorts alphanumerically, so we would need to use an alphanumeric
     comparison to find elements using bsearch. here we sort numerically by pid*/
  qsort(new_procs->procs, new_procs->count, sizeof(*new_procs->procs), proc_pid_cmp);
}

void free_procs(struct proc_list *p)
{
  free(p->procs);
}

void usage_and_die(const char *argv0)
{
  fprintf(stderr, "Usage: %s [options]\n"
      "\n"
      "      -i, --interval=<interval>  sampling interval in seconds (%d)\n"
      "      -n, --num=<num>            number of processes to sample (%d)\n"
      "      -o, --oneshot              one-shot mode, do not loop\n"
      "      -p, --path=<path>          path for process stat files (%s)\n"
      "      -w, --warmup=<warmup>      seconds to wait before sampling begins (%d)\n",
      argv0, DEFAULT_READ_INTERVAL, DEFAULT_PROCS_TO_SAMPLE,
      DEFAULT_PROC_GLOB_PATH, DEFAULT_WARMUP_SECONDS);
  exit(1);
}

int main(int argc, char **argv)
{
  struct proc_list old_procs = {0, 0};
  struct proc_list new_procs = {0, 0};
  int read_interval = DEFAULT_READ_INTERVAL;
  int procs_to_sample = DEFAULT_PROCS_TO_SAMPLE;
  int warmup_seconds = DEFAULT_WARMUP_SECONDS;

  int one_shot_mode = false;
  const char *proc_glob_path = DEFAULT_PROC_GLOB_PATH;

  struct option long_options[] = {
    {"interval", required_argument, 0, 'i'},
    {"num",      required_argument, 0, 'n'},
    {"oneshot",  no_argument,       0, 'o'},
    {"path",     required_argument, 0, 'p'},
    {"warmup",   required_argument, 0, 'w'},
    {0,          0,                 0, 0},
  };

  int c;
  while ((c = getopt_long(argc, argv, "i:n:w:p:o", long_options, NULL)) != -1) {
    switch (c) {
    case 'i':
      read_interval = atoi(optarg);
      if (read_interval < 1)
        die("invalid argument");
      break;
    case 'n':
      procs_to_sample = atoi(optarg);
      if (procs_to_sample < 1)
        die("invalid argument");
      break;
    case 'o':
      one_shot_mode = true;
      break;
    case 'p':
      proc_glob_path = optarg;
      break;
    case 'w':
      warmup_seconds = atoi(optarg);
      if (warmup_seconds < 0)
        die("invalid argument");
      break;
    default:
      usage_and_die(argv[0]);
    }
  }

  if (optind < argc)
    usage_and_die(argv[0]);

  setlinebuf(stdout);

  ticks_per_sec = sysconf(_SC_CLK_TCK);

  sleep(warmup_seconds);

  read_procs(&old_procs, proc_glob_path);
  for (;;) {
    sleep(read_interval);
    read_procs(&new_procs, proc_glob_path);
    print_top(&new_procs, &old_procs, procs_to_sample, read_interval);
    free_procs(&old_procs);
    old_procs = new_procs;

    if (one_shot_mode)
      exit(0);
  }
}
