#include <stdlib.h>

#include "util.h"
#include "values.h"

void perf_read_values_init(struct perf_read_values *values)
{
	values->threads_max = 16;
	values->pid = malloc(values->threads_max * sizeof(*values->pid));
	values->tid = malloc(values->threads_max * sizeof(*values->tid));
	values->value = malloc(values->threads_max * sizeof(*values->value));
	if (!values->pid || !values->tid || !values->value)
		die("failed to allocate read_values threads arrays");
	values->threads = 0;

	values->counters_max = 16;
	values->counterrawid = malloc(values->counters_max
				      * sizeof(*values->counterrawid));
	values->countername = malloc(values->counters_max
				     * sizeof(*values->countername));
	if (!values->counterrawid || !values->countername)
		die("failed to allocate read_values counters arrays");
	values->counters = 0;
}

void perf_read_values_destroy(struct perf_read_values *values)
{
	int i;

	if (!values->threads_max || !values->counters_max)
		return;

	for (i = 0; i < values->threads; i++)
		free(values->value[i]);
	free(values->value);
	free(values->pid);
	free(values->tid);
	free(values->counterrawid);
	for (i = 0; i < values->counters; i++)
		free(values->countername[i]);
	free(values->countername);
}

static void perf_read_values__enlarge_threads(struct perf_read_values *values)
{
	values->threads_max *= 2;
	values->pid = realloc(values->pid,
			      values->threads_max * sizeof(*values->pid));
	values->tid = realloc(values->tid,
			      values->threads_max * sizeof(*values->tid));
	values->value = realloc(values->value,
				values->threads_max * sizeof(*values->value));
	if (!values->pid || !values->tid || !values->value)
		die("failed to enlarge read_values threads arrays");
}

static int perf_read_values__findnew_thread(struct perf_read_values *values,
					    u32 pid, u32 tid)
{
	int i;

	for (i = 0; i < values->threads; i++)
		if (values->pid[i] == pid && values->tid[i] == tid)
			return i;

	if (values->threads == values->threads_max)
		perf_read_values__enlarge_threads(values);

	i = values->threads++;
	values->pid[i] = pid;
	values->tid[i] = tid;
	values->value[i] = malloc(values->counters_max * sizeof(**values->value));
	if (!values->value[i])
		die("failed to allocate read_values counters array");

	return i;
}

static void perf_read_values__enlarge_counters(struct perf_read_values *values)
{
	int i;

	values->counters_max *= 2;
	values->counterrawid = realloc(values->counterrawid,
				       values->counters_max * sizeof(*values->counterrawid));
	values->countername = realloc(values->countername,
				      values->counters_max * sizeof(*values->countername));
	if (!values->counterrawid || !values->countername)
		die("failed to enlarge read_values counters arrays");

	for (i = 0; i < values->threads; i++) {
		values->value[i] = realloc(values->value[i],
					   values->counters_max * sizeof(**values->value));
		if (!values->value[i])
			die("failed to enlarge read_values counters arrays");
	}
}

static int perf_read_values__findnew_counter(struct perf_read_values *values,
					     u64 rawid, const char *name)
{
	int i;

	for (i = 0; i < values->counters; i++)
		if (values->counterrawid[i] == rawid)
			return i;

	if (values->counters == values->counters_max)
		perf_read_values__enlarge_counters(values);

	i = values->counters++;
	values->counterrawid[i] = rawid;
	values->countername[i] = strdup(name);

	return i;
}

void perf_read_values_add_value(struct perf_read_values *values,
				u32 pid, u32 tid,
				u64 rawid, const char *name, u64 value)
{
	int tindex, cindex;

	tindex = perf_read_values__findnew_thread(values, pid, tid);
	cindex = perf_read_values__findnew_counter(values, rawid, name);

	values->value[tindex][cindex] = value;
}

static void perf_read_values__display_pretty(FILE *fp,
					     struct perf_read_values *values)
{
	int i, j;
	int pidwidth, tidwidth;
	int *counterwidth;

	counterwidth = malloc(values->counters * sizeof(*counterwidth));
	if (!counterwidth)
		die("failed to allocate counterwidth array");
	tidwidth = 3;
	pidwidth = 3;
	for (j = 0; j < values->counters; j++)
		counterwidth[j] = strlen(values->countername[j]);
	for (i = 0; i < values->threads; i++) {
		int width;

		width = snprintf(NULL, 0, "%d", values->pid[i]);
		if (width > pidwidth)
			pidwidth = width;
		width = snprintf(NULL, 0, "%d", values->tid[i]);
		if (width > tidwidth)
			tidwidth = width;
		for (j = 0; j < values->counters; j++) {
			width = snprintf(NULL, 0, "%" PRIu64, values->value[i][j]);
			if (width > counterwidth[j])
				counterwidth[j] = width;
		}
	}

	fprintf(fp, "# %*s  %*s", pidwidth, "PID", tidwidth, "TID");
	for (j = 0; j < values->counters; j++)
		fprintf(fp, "  %*s", counterwidth[j], values->countername[j]);
	fprintf(fp, "\n");

	for (i = 0; i < values->threads; i++) {
		fprintf(fp, "  %*d  %*d", pidwidth, values->pid[i],
			tidwidth, values->tid[i]);
		for (j = 0; j < values->counters; j++)
			fprintf(fp, "  %*" PRIu64,
				counterwidth[j], values->value[i][j]);
		fprintf(fp, "\n");
	}
	free(counterwidth);
}

static void perf_read_values__display_raw(FILE *fp,
					  struct perf_read_values *values)
{
	int width, pidwidth, tidwidth, namewidth, rawwidth, countwidth;
	int i, j;

	tidwidth = 3; /* TID */
	pidwidth = 3; /* PID */
	namewidth = 4; /* "Name" */
	rawwidth = 3; /* "Raw" */
	countwidth = 5; /* "Count" */

	for (i = 0; i < values->threads; i++) {
		width = snprintf(NULL, 0, "%d", values->pid[i]);
		if (width > pidwidth)
			pidwidth = width;
		width = snprintf(NULL, 0, "%d", values->tid[i]);
		if (width > tidwidth)
			tidwidth = width;
	}
	for (j = 0; j < values->counters; j++) {
		width = strlen(values->countername[j]);
		if (width > namewidth)
			namewidth = width;
		width = snprintf(NULL, 0, "%" PRIx64, values->counterrawid[j]);
		if (width > rawwidth)
			rawwidth = width;
	}
	for (i = 0; i < values->threads; i++) {
		for (j = 0; j < values->counters; j++) {
			width = snprintf(NULL, 0, "%" PRIu64, values->value[i][j]);
			if (width > countwidth)
				countwidth = width;
		}
	}

	fprintf(fp, "# %*s  %*s  %*s  %*s  %*s\n",
		pidwidth, "PID", tidwidth, "TID",
		namewidth, "Name", rawwidth, "Raw",
		countwidth, "Count");
	for (i = 0; i < values->threads; i++)
		for (j = 0; j < values->counters; j++)
			fprintf(fp, "  %*d  %*d  %*s  %*" PRIx64 "  %*" PRIu64,
				pidwidth, values->pid[i],
				tidwidth, values->tid[i],
				namewidth, values->countername[j],
				rawwidth, values->counterrawid[j],
				countwidth, values->value[i][j]);
}

void perf_read_values_display(FILE *fp, struct perf_read_values *values, int raw)
{
	if (raw)
		perf_read_values__display_raw(fp, values);
	else
		perf_read_values__display_pretty(fp, values);
}
