// 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/listnode.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>

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 = 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;
      int 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;
}
