// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <fcntl.h>
#include <inttypes.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/exception.h>
#include <zircon/syscalls/object.h>
#include <zircon/time.h>
#include <zircon/types.h>

#include <pretty/sizes.h>
#include <task-utils/get.h>
#include <task-utils/walker.h>

#include "src/lib/listnode/listnode.h"

enum sort_order { UNSORTED, SORT_TIME_DELTA };

typedef struct {
  struct list_node node;

  // has it been seen this pass?
  bool scanned;
  zx_duration_t delta_time;

  // information about the thread
  zx_koid_t proc_koid;
  zx_koid_t koid;
  zx_info_thread_t info;
  zx_info_thread_stats_t stats;
  char name[ZX_MAX_NAME_LEN];
  char proc_name[ZX_MAX_NAME_LEN];
} thread_info_t;

// arguments
static zx_duration_t delay = ZX_SEC(1);
static int count = -1;
static bool print_all = false;
static bool raw_time = false;
static enum sort_order sort_order = SORT_TIME_DELTA;

// active locals
static struct list_node thread_list = LIST_INITIAL_VALUE(thread_list);
static char last_process_name[ZX_MAX_NAME_LEN];
static zx_koid_t last_process_scanned;

// Return text representation of thread state.
static const char* state_string(const zx_info_thread_t* info) {
  if (info->wait_exception_channel_type != ZX_EXCEPTION_CHANNEL_TYPE_NONE) {
    return "excp";
  } else {
    switch (ZX_THREAD_STATE_BASIC(info->state)) {
      case ZX_THREAD_STATE_NEW:
        return "new";
      case ZX_THREAD_STATE_RUNNING:
        return "run";
      case ZX_THREAD_STATE_SUSPENDED:
        return "susp";
      case ZX_THREAD_STATE_BLOCKED:
        return "block";
      case ZX_THREAD_STATE_DYING:
        return "dying";
      case ZX_THREAD_STATE_DEAD:
        return "dead";
      default:
        return "???";
    }
  }
}

static zx_status_t process_callback(void* unused_ctx, int depth, zx_handle_t proc, zx_koid_t koid,
                                    zx_koid_t parent_koid) {
  last_process_scanned = koid;

  zx_status_t status =
      zx_object_get_property(proc, ZX_PROP_NAME, &last_process_name, sizeof(last_process_name));
  return status;
}

// Adds a thread's information to the thread_list
static zx_status_t thread_callback(void* unused_ctx, int depth, zx_handle_t thread, zx_koid_t koid,
                                   zx_koid_t parent_koid) {
  thread_info_t e = {};

  e.koid = koid;
  e.scanned = true;

  e.proc_koid = last_process_scanned;
  strlcpy(e.proc_name, last_process_name, sizeof(e.proc_name));

  zx_status_t status = zx_object_get_property(thread, ZX_PROP_NAME, e.name, sizeof(e.name));
  if (status != ZX_OK) {
    return status;
  }
  status = zx_object_get_info(thread, ZX_INFO_THREAD, &e.info, sizeof(e.info), NULL, NULL);
  if (status != ZX_OK) {
    return status;
  }
  status = zx_object_get_info(thread, ZX_INFO_THREAD_STATS, &e.stats, sizeof(e.stats), NULL, NULL);
  if (status != ZX_OK) {
    return status;
  }

  // see if this thread is in the list
  thread_info_t* temp;
  list_for_every_entry (&thread_list, temp, thread_info_t, node) {
    if (e.koid == temp->koid) {
      // mark it scanned, compute the delta time,
      // and copy the new state over
      temp->scanned = true;
      temp->delta_time = zx_duration_sub_duration(e.stats.total_runtime, temp->stats.total_runtime);
      temp->info = e.info;
      temp->stats = e.stats;
      return ZX_OK;
    }
  }

  // it wasn't in the list, add it
  thread_info_t* new_entry = malloc(sizeof(thread_info_t));
  *new_entry = e;

  list_add_tail(&thread_list, &new_entry->node);

  return ZX_OK;
}

static void sort_threads(enum sort_order order) {
  if (order == UNSORTED)
    return;

  struct list_node new_list = LIST_INITIAL_VALUE(new_list);

  // cheezy sort into second list, then swap back to first
  thread_info_t* e;
  while ((e = list_remove_head_type(&thread_list, thread_info_t, node))) {
    thread_info_t* t;

    bool found = false;
    list_for_every_entry (&new_list, t, thread_info_t, node) {
      if (order == SORT_TIME_DELTA) {
        if (e->delta_time > t->delta_time) {
          list_add_before(&t->node, &e->node);
          found = true;
          break;
        }
      }
    }

    // walked off the end
    if (!found)
      list_add_tail(&new_list, &e->node);
  }

  list_move(&new_list, &thread_list);
}

static void print_threads(void) {
  thread_info_t* e;
  printf("%8s %8s %10s %4s %5s %s\n", "PID", "TID", raw_time ? "TIME_NS" : "TIME%", "CPU", "STATE",
         "NAME");

  int i = 0;
  list_for_every_entry (&thread_list, e, thread_info_t, node) {
    // only print threads that are active
    if (!print_all && e->delta_time == 0)
      continue;

    if (!raw_time) {
      double percent = 0;
      if (e->delta_time > 0)
        percent = (double)e->delta_time / (double)delay * 100;

      printf("%8lu %8lu %10.2f %4u %5s %s:%s\n", e->proc_koid, e->koid, percent,
             e->stats.last_scheduled_cpu, state_string(&e->info), e->proc_name, e->name);
    } else {
      printf("%8lu %8lu %10lu %4u %5s %s:%s\n", e->proc_koid, e->koid, e->delta_time,
             e->stats.last_scheduled_cpu, state_string(&e->info), e->proc_name, e->name);
    }

    // only print the first count items (or all, if count < 0)
    if (++i == count)
      break;
  }
}

static void print_help(FILE* f) {
  fprintf(f, "Usage: top [options]\n");
  fprintf(f, "Options:\n");
  fprintf(f, " -a              Print all threads, even if inactive\n");
  fprintf(f, " -c <count>      Print the first count threads (default infinity)\n");
  fprintf(f, " -d <delay>      Delay in seconds (default 1 second)\n");
  fprintf(f, " -j <jobid>      Show only threads that belong to a given jobid\n");
  fprintf(f, " -n <times>      Run this many times and then exit\n");
  fprintf(f, " -o <sort field> Sort by different fields (default is time)\n");
  fprintf(f, " -r              Print raw time in nanoseconds\n");
  fprintf(f, "\nSupported sort fields:\n");
  fprintf(f, "\tnone : no sorting, in job order\n");
  fprintf(f, "\ttime : sort by delta time between scans\n");
}

int main(int argc, char** argv) {
  zx_handle_t target_job = ZX_HANDLE_INVALID;

  int num_loops = -1;
  for (int i = 1; i < argc; ++i) {
    const char* arg = argv[i];
    if (!strcmp(arg, "--help") || !strcmp(arg, "-h")) {
      print_help(stdout);
      return 0;
    }
    if (!strcmp(arg, "-a")) {
      print_all = true;
    } else if (!strcmp(arg, "-d")) {
      delay = 0;
      if (i + 1 < argc) {
        delay = ZX_SEC(atoi(argv[i + 1]));
      }
      if (delay == 0) {
        fprintf(stderr, "Bad -d value '%s'\n", argv[i + 1]);
        print_help(stderr);
        return 1;
      }
      i++;
    } else if (!strcmp(arg, "-n")) {
      num_loops = 0;
      if (i + 1 < argc) {
        num_loops = atoi(argv[i + 1]);
      }
      if (num_loops == 0) {
        fprintf(stderr, "Bad -n value '%s'\n", argv[i + 1]);
        print_help(stderr);
        return 1;
      }
      i++;
    } else if (!strcmp(arg, "-c")) {
      count = 0;
      if (i + 1 < argc) {
        count = atoi(argv[i + 1]);
      }
      if (count == 0) {
        fprintf(stderr, "Bad count\n");
        print_help(stderr);
        return 1;
      }
      i++;
    } else if (!strcmp(arg, "-o")) {
      if (i + 1 >= argc) {
        fprintf(stderr, "Bad sort field\n");
        print_help(stderr);
        return 1;
      } else if (!strcmp(argv[i + 1], "none")) {
        sort_order = UNSORTED;
      } else if (!strcmp(argv[i + 1], "time")) {
        sort_order = SORT_TIME_DELTA;
      } else {
        fprintf(stderr, "Bad sort field\n");
        print_help(stderr);
        return 1;
      }
      i++;
    } else if (!strcmp(arg, "-r")) {
      raw_time = true;
    } else if (!strcmp(arg, "-j")) {
      if (i + 1 >= argc) {
        fprintf(stderr, "Bad job field\n");
        print_help(stderr);
        return 1;
      }
      int jobid = atoi(argv[i + 1]);
      zx_obj_type_t type;
      zx_status_t status = get_task_by_koid(jobid, &type, &target_job);
      if (status != ZX_OK) {
        fprintf(stderr, "ERROR: get_task_by_koid failed: %s (%d)\n", zx_status_get_string(status),
                status);
        return 1;
      }
      if (type != ZX_OBJ_TYPE_JOB) {
        fprintf(stderr, "ERROR: object with koid %d is not a job\n", jobid);
        return 1;
      }
      i++;
    } else {
      fprintf(stderr, "Unknown option: %s\n", arg);
      print_help(stderr);
      return 1;
    }
  }

  bool is_term = false;
  const char* term = getenv("TERM");
  if (term != NULL) {
    if (!strncmp(term, "screen", 6)) {
      is_term = true;
    }
    if (!strncmp(term, "xterm", 5)) {
      is_term = true;
    }
  }

  // set stdin to non blocking
  fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);

  int ret = 0;
  bool first_run = true;
  for (;;) {
    zx_time_t next_deadline = zx_deadline_after(delay);

    // mark all active threads as not scanned
    thread_info_t* e;
    list_for_every_entry (&thread_list, e, thread_info_t, node) { e->scanned = false; }

    // If we have a target job, only walk the target subtree. Otherwise walk from root.
    zx_status_t status;
    if (target_job != ZX_HANDLE_INVALID) {
      status = walk_job_tree(target_job, NULL, process_callback, thread_callback, NULL);
    } else {
      status = walk_root_job_tree(NULL, process_callback, thread_callback, NULL);
    }
    if (status != ZX_OK) {
      fprintf(stderr, "WARNING: walking the job tree failed: %s (%d)\n",
              zx_status_get_string(status), status);
      ret = 1;
      goto finish;
    }

    // remove every entry that hasn't been scanned this pass
    thread_info_t* temp;
    list_for_every_entry_safe (&thread_list, e, temp, thread_info_t, node) {
      if (!e->scanned) {
        list_delete(&e->node);
        free(e);
      }
    }

    if (first_run) {
      // We don't have data until after we scan twice, since we're
      // computing deltas.
      first_run = false;
      continue;
    }

    // sort the list
    sort_threads(sort_order);

    // dump the list of threads
    if (is_term) {
      printf("\E[H\E[J");
    }
    print_threads();

    if (num_loops > 0) {
      if (--num_loops == 0) {
        break;
      }
    } else {
      // TODO: replace once ctrl-c works in the shell
      char c;
      long err;
      while ((err = read(STDIN_FILENO, &c, 1)) > 0) {
        if (c == 0x3) {
          ret = 0;
          goto finish;
        }
      }
    }

    zx_nanosleep(next_deadline);
  }

finish:
  if (target_job != ZX_HANDLE_INVALID) {
    zx_handle_close(target_job);
  }
  return ret;
}
