/*
 *  (C) 2010,2011       Thomas Renninger <trenn@suse.de>, Novell Inc.
 *
 *  Licensed under the terms of the GNU GPL License version 2.
 *
 *  Output format inspired by Len Brown's <lenb@kernel.org> turbostat tool.
 *
 */


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <libgen.h>

#include "idle_monitor/cpupower-monitor.h"
#include "idle_monitor/idle_monitors.h"
#include "helpers/helpers.h"

/* Define pointers to all monitors.  */
#define DEF(x) & x ## _monitor ,
struct cpuidle_monitor *all_monitors[] = {
#include "idle_monitors.def"
0
};

static struct cpuidle_monitor *monitors[MONITORS_MAX];
static unsigned int avail_monitors;

static char *progname;

enum operation_mode_e { list = 1, show, show_all };
static int mode;
static int interval = 1;
static char *show_monitors_param;
static struct cpupower_topology cpu_top;

/* ToDo: Document this in the manpage */
static char range_abbr[RANGE_MAX] = { 'T', 'C', 'P', 'M', };

static void print_wrong_arg_exit(void)
{
	printf(_("invalid or unknown argument\n"));
	exit(EXIT_FAILURE);
}

long long timespec_diff_us(struct timespec start, struct timespec end)
{
	struct timespec temp;
	if ((end.tv_nsec - start.tv_nsec) < 0) {
		temp.tv_sec = end.tv_sec - start.tv_sec - 1;
		temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
	} else {
		temp.tv_sec = end.tv_sec - start.tv_sec;
		temp.tv_nsec = end.tv_nsec - start.tv_nsec;
	}
	return (temp.tv_sec * 1000000) + (temp.tv_nsec / 1000);
}

void print_n_spaces(int n)
{
	int x;
	for (x = 0; x < n; x++)
		printf(" ");
}

/* size of s must be at least n + 1 */
int fill_string_with_spaces(char *s, int n)
{
	int len = strlen(s);
	if (len > n)
		return -1;
	for (; len < n; len++)
		s[len] = ' ';
	s[len] = '\0';
	return 0;
}

void print_header(int topology_depth)
{
	int unsigned mon;
	int state, need_len, pr_mon_len;
	cstate_t s;
	char buf[128] = "";
	int percent_width = 4;

	fill_string_with_spaces(buf, topology_depth * 5 - 1);
	printf("%s|", buf);

	for (mon = 0; mon < avail_monitors; mon++) {
		pr_mon_len = 0;
		need_len = monitors[mon]->hw_states_num * (percent_width + 3)
			- 1;
		if (mon != 0) {
			printf("|| ");
			need_len--;
		}
		sprintf(buf, "%s", monitors[mon]->name);
		fill_string_with_spaces(buf, need_len);
		printf("%s", buf);
	}
	printf("\n");

	if (topology_depth > 2)
		printf("PKG |");
	if (topology_depth > 1)
		printf("CORE|");
	if (topology_depth > 0)
		printf("CPU |");

	for (mon = 0; mon < avail_monitors; mon++) {
		if (mon != 0)
			printf("|| ");
		else
			printf(" ");
		for (state = 0; state < monitors[mon]->hw_states_num; state++) {
			if (state != 0)
				printf(" | ");
			s = monitors[mon]->hw_states[state];
			sprintf(buf, "%s", s.name);
			fill_string_with_spaces(buf, percent_width);
			printf("%s", buf);
		}
		printf(" ");
	}
	printf("\n");
}


void print_results(int topology_depth, int cpu)
{
	unsigned int mon;
	int state, ret;
	double percent;
	unsigned long long result;
	cstate_t s;

	/* Be careful CPUs may got resorted for pkg value do not just use cpu */
	if (!bitmask_isbitset(cpus_chosen, cpu_top.core_info[cpu].cpu))
		return;

	if (topology_depth > 2)
		printf("%4d|", cpu_top.core_info[cpu].pkg);
	if (topology_depth > 1)
		printf("%4d|", cpu_top.core_info[cpu].core);
	if (topology_depth > 0)
		printf("%4d|", cpu_top.core_info[cpu].cpu);

	for (mon = 0; mon < avail_monitors; mon++) {
		if (mon != 0)
			printf("||");

		for (state = 0; state < monitors[mon]->hw_states_num; state++) {
			if (state != 0)
				printf("|");

			s = monitors[mon]->hw_states[state];

			if (s.get_count_percent) {
				ret = s.get_count_percent(s.id, &percent,
						  cpu_top.core_info[cpu].cpu);
				if (ret)
					printf("******");
				else if (percent >= 100.0)
					printf("%6.1f", percent);
				else
					printf("%6.2f", percent);
			} else if (s.get_count) {
				ret = s.get_count(s.id, &result,
						  cpu_top.core_info[cpu].cpu);
				if (ret)
					printf("******");
				else
					printf("%6llu", result);
			} else {
				printf(_("Monitor %s, Counter %s has no count "
					 "function. Implementation error\n"),
				       monitors[mon]->name, s.name);
				exit(EXIT_FAILURE);
			}
		}
	}
	/*
	 * The monitor could still provide useful data, for example
	 * AMD HW counters partly sit in PCI config space.
	 * It's up to the monitor plug-in to check .is_online, this one
	 * is just for additional info.
	 */
	if (!cpu_top.core_info[cpu].is_online) {
		printf(_(" *is offline\n"));
		return;
	} else
		printf("\n");
}


/* param: string passed by -m param (The list of monitors to show)
 *
 * Monitors must have been registered already, matching monitors
 * are picked out and available monitors array is overridden
 * with matching ones
 *
 * Monitors get sorted in the same order the user passes them
*/

static void parse_monitor_param(char *param)
{
	unsigned int num;
	int mon, hits = 0;
	char *tmp = param, *token;
	struct cpuidle_monitor *tmp_mons[MONITORS_MAX];


	for (mon = 0; mon < MONITORS_MAX; mon++, tmp = NULL) {
		token = strtok(tmp, ",");
		if (token == NULL)
			break;
		if (strlen(token) >= MONITOR_NAME_LEN) {
			printf(_("%s: max monitor name length"
				 " (%d) exceeded\n"), token, MONITOR_NAME_LEN);
			continue;
		}

		for (num = 0; num < avail_monitors; num++) {
			if (!strcmp(monitors[num]->name, token)) {
				dprint("Found requested monitor: %s\n", token);
				tmp_mons[hits] = monitors[num];
				hits++;
			}
		}
	}
	if (hits == 0) {
		printf(_("No matching monitor found in %s, "
			 "try -l option\n"), param);
		exit(EXIT_FAILURE);
	}
	/* Override detected/registerd monitors array with requested one */
	memcpy(monitors, tmp_mons,
		sizeof(struct cpuidle_monitor *) * MONITORS_MAX);
	avail_monitors = hits;
}

void list_monitors(void)
{
	unsigned int mon;
	int state;
	cstate_t s;

	for (mon = 0; mon < avail_monitors; mon++) {
		printf(_("Monitor \"%s\" (%d states) - Might overflow after %u "
			 "s\n"),
			monitors[mon]->name, monitors[mon]->hw_states_num,
			monitors[mon]->overflow_s);

		for (state = 0; state < monitors[mon]->hw_states_num; state++) {
			s = monitors[mon]->hw_states[state];
			/*
			 * ToDo show more state capabilities:
			 * percent, time (granlarity)
			 */
			printf("%s\t[%c] -> %s\n", s.name, range_abbr[s.range],
			       gettext(s.desc));
		}
	}
}

int fork_it(char **argv)
{
	int status;
	unsigned int num;
	unsigned long long timediff;
	pid_t child_pid;
	struct timespec start, end;

	child_pid = fork();
	clock_gettime(CLOCK_REALTIME, &start);

	for (num = 0; num < avail_monitors; num++)
		monitors[num]->start();

	if (!child_pid) {
		/* child */
		execvp(argv[0], argv);
	} else {
		/* parent */
		if (child_pid == -1) {
			perror("fork");
			exit(1);
		}

		signal(SIGINT, SIG_IGN);
		signal(SIGQUIT, SIG_IGN);
		if (waitpid(child_pid, &status, 0) == -1) {
			perror("wait");
			exit(1);
		}
	}
	clock_gettime(CLOCK_REALTIME, &end);
	for (num = 0; num < avail_monitors; num++)
		monitors[num]->stop();

	timediff = timespec_diff_us(start, end);
	if (WIFEXITED(status))
		printf(_("%s took %.5f seconds and exited with status %d\n"),
			argv[0], timediff / (1000.0 * 1000),
			WEXITSTATUS(status));
	return 0;
}

int do_interval_measure(int i)
{
	unsigned int num;

	for (num = 0; num < avail_monitors; num++) {
		dprint("HW C-state residency monitor: %s - States: %d\n",
		       monitors[num]->name, monitors[num]->hw_states_num);
		monitors[num]->start();
	}
	sleep(i);
	for (num = 0; num < avail_monitors; num++)
		monitors[num]->stop();

	return 0;
}

static void cmdline(int argc, char *argv[])
{
	int opt;
	progname = basename(argv[0]);

	while ((opt = getopt(argc, argv, "+li:m:")) != -1) {
		switch (opt) {
		case 'l':
			if (mode)
				print_wrong_arg_exit();
			mode = list;
			break;
		case 'i':
			/* only allow -i with -m or no option */
			if (mode && mode != show)
				print_wrong_arg_exit();
			interval = atoi(optarg);
			break;
		case 'm':
			if (mode)
				print_wrong_arg_exit();
			mode = show;
			show_monitors_param = optarg;
			break;
		default:
			print_wrong_arg_exit();
		}
	}
	if (!mode)
		mode = show_all;
}

int cmd_monitor(int argc, char **argv)
{
	unsigned int num;
	struct cpuidle_monitor *test_mon;
	int cpu;

	cmdline(argc, argv);
	cpu_count = get_cpu_topology(&cpu_top);
	if (cpu_count < 0) {
		printf(_("Cannot read number of available processors\n"));
		return EXIT_FAILURE;
	}

	/* Default is: monitor all CPUs */
	if (bitmask_isallclear(cpus_chosen))
		bitmask_setall(cpus_chosen);

	dprint("System has up to %d CPU cores\n", cpu_count);

	for (num = 0; all_monitors[num]; num++) {
		dprint("Try to register: %s\n", all_monitors[num]->name);
		test_mon = all_monitors[num]->do_register();
		if (test_mon) {
			if (test_mon->needs_root && !run_as_root) {
				fprintf(stderr, _("Available monitor %s needs "
					  "root access\n"), test_mon->name);
				continue;
			}
			monitors[avail_monitors] = test_mon;
			dprint("%s registered\n", all_monitors[num]->name);
			avail_monitors++;
		}
	}

	if (avail_monitors == 0) {
		printf(_("No HW Cstate monitors found\n"));
		return 1;
	}

	if (mode == list) {
		list_monitors();
		exit(EXIT_SUCCESS);
	}

	if (mode == show)
		parse_monitor_param(show_monitors_param);

	dprint("Packages: %d - Cores: %d - CPUs: %d\n",
	       cpu_top.pkgs, cpu_top.cores, cpu_count);

	/*
	 * if any params left, it must be a command to fork
	 */
	if (argc - optind)
		fork_it(argv + optind);
	else
		do_interval_measure(interval);

	/* ToDo: Topology parsing needs fixing first to do
	   this more generically */
	if (cpu_top.pkgs > 1)
		print_header(3);
	else
		print_header(1);

	for (cpu = 0; cpu < cpu_count; cpu++) {
		if (cpu_top.pkgs > 1)
			print_results(3, cpu);
		else
			print_results(1, cpu);
	}

	for (num = 0; num < avail_monitors; num++)
		monitors[num]->unregister();

	cpu_topology_release(cpu_top);
	return 0;
}
