/*
 * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
 * Distributed under the terms of the GNU General Public License v2
 */

#include <sys/syscall.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <debug.h>
#include <eprintf.h>
#include <style.h>

#include "ktop.h"

bool Halt = FALSE;

bool Dump = FALSE;
bool Trace_exit = TRUE;
bool Trace_self = FALSE;
bool Pause = FALSE;
bool Help = FALSE;
char *Log_file = NULL;

Display_s Display;

pid_t gettid(void) { return syscall(__NR_gettid); }

u8 Ignore_pid[(MAX_PID + 4) / 8];
pthread_mutex_t Ignore_pid_lock = PTHREAD_MUTEX_INITIALIZER;
u64 Ignored_pid_count;

void ignore_pid(int pid)
{
	if ((pid < 0) || (pid >= MAX_PID)) warn("pid out of range %d", pid);

	pthread_mutex_lock(&Ignore_pid_lock);
	Ignore_pid[pid / 8] |= (1 << (pid & 0x7));
	pthread_mutex_unlock(&Ignore_pid_lock);
}

bool do_ignore_pid(int pid)
{
	if ((pid < 0) || (pid >= MAX_PID)) {
		warn("pid out of range %d", pid);
		return TRUE;
	}
	if (Ignore_pid[pid / 8] & (1 << (pid & 0x7))) {
		++Ignored_pid_count;
		return TRUE;
	} else {
		return FALSE;
	}
}


void cleanup(int sig)
{
	cleanup_collector();
	cleanup_display();
	if (sig) {
		fatal("killed by signal %d\n", sig);
	}
	exit(0);
}

void set_signals(void)
{
	signal(SIGHUP,	cleanup);
	signal(SIGINT,	cleanup);
	signal(SIGQUIT,	cleanup);
	signal(SIGILL,	cleanup);
	signal(SIGTRAP,	cleanup);
	signal(SIGABRT,	cleanup);
	signal(SIGBUS,	cleanup);
	signal(SIGFPE,	cleanup);
	signal(SIGKILL,	cleanup);
	signal(SIGSEGV,	cleanup);
	signal(SIGPIPE,	cleanup);
	signal(SIGSTOP,	cleanup);
	signal(SIGTSTP,	cleanup);
}

static void usage(void)
{
	fprintf(stderr, "usage: %s [-dhs] [-l <log path name>]\n"
		"\td - dump of ftrace log of cpu 0 for debugging\n"
		"\th - usage\n"
		"\tl - create a log file\n"
		"\ts - trace self\n\n"
		"\tCommands while running:\n"
		"\t? - help for current screen\n"
		"\tq - quit\n"
		"\tc - reset internal counters\n"
		"\tk - display top kernel operations (default)\n"
		"\tg - display graph of selected operation\n"
		"\tf - display just file system operations\n"
		"\ti - display counters internal to ktop for debugging\n"
		"\tp - toggle pause\n"
		"\ts - display summary\n"
		"\t< - reduce redisplay interval\n"
		"\t> - increase redisplay interval\n",
		getprogname());
	exit(2);
}

static void init(int argc, char *argv[])
{
	int c;

	setprogname(argv[0]);
	set_signals();

	while ((c = getopt(argc, argv, "dhsl:")) != -1) {
		switch (c) {
		case 'd':
			Dump = TRUE;
			break;
		case 's':
			Trace_self = TRUE;
			break;
		case 'h':
			usage();
			break;
		case 'l':
			Log_file = optarg;
			break;
		default:
			fprintf(stderr, "unknown flag '%c'\n", c);
			usage();
			break;
		}
	}
	Display = Kernel_display;
}

void quit(void)
{
	Halt = TRUE;
}

void clear(void)
{
	reset_reduce();
}

void commander(void)
{
	for (;;) {
		int c = getchar();
		if (c == EOF) cleanup(0);
		switch (c) {
		case 'q':
			quit();
			return;
		case 'c':
			clear();
			break;
		case '<':
			decrease_reduce_interval();
			break;
		case '>':
			increase_reduce_interval();
			break;
		case '?':
			Help = !Help;
			break;
		case 'i':
			Display = Internal_display;
			break;
		case 'k':
			Display = Kernel_display;
			break;
		case 'g':
			Display = Plot_display;
			break;
		case 'f':
			Display = File_system_display;
			break;
		case 's':
			Display = Summary_display;
			break;
		case 'p':
			Pause = !Pause;
			break;
		default:
			Pause = FALSE;
			Help = FALSE;
			break;
		}
	}
}

int main(int argc, char **argv)
{
	pthread_t reduce_thread;
	int rc;

	debugstderr();
	assert(Num_syscalls <= (1 << SYSCALL_SHIFT));

	init(argc, argv);

	ignore_pid(gettid());

	start_collector();

	if (!Dump) {
		rc = pthread_create(&reduce_thread, NULL, reduce, NULL);
		if (rc) fatal("creating reduce thread:");
		if (Log_file) log_open(Log_file);
	}
	commander();

	cleanup(0);
	return 0;
}
