// SPDX-License-Identifier: GPL-2.0
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <linux/zalloc.h>

#include "values.h"
#include "debug.h"
#include "evsel.h"

int perf_read_values_init(struct perf_read_values *values)
{
	values->threads_max = 16;
	values->pid = calloc(values->threads_max, sizeof(*values->pid));
	values->tid = calloc(values->threads_max, sizeof(*values->tid));
	values->value = calloc(values->threads_max, sizeof(*values->value));
	if (!values->pid || !values->tid || !values->value) {
		pr_debug("failed to allocate read_values threads arrays");
		goto out_free_pid;
	}
	values->threads = 0;

	values->counters_max = 16;
	values->counters = malloc(values->counters_max * sizeof(*values->counters));
	if (!values->counters) {
		pr_debug("failed to allocate read_values counters array");
		goto out_free_counter;
	}
	values->num_counters = 0;

	return 0;

out_free_counter:
	zfree(&values->counters);
out_free_pid:
	zfree(&values->pid);
	zfree(&values->tid);
	zfree(&values->value);
	return -ENOMEM;
}

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++)
		zfree(&values->value[i]);
	zfree(&values->value);
	zfree(&values->pid);
	zfree(&values->tid);
	zfree(&values->counters);
}

static int perf_read_values__enlarge_threads(struct perf_read_values *values)
{
	int nthreads_max = values->threads_max * 2;
	void *npid = realloc(values->pid, nthreads_max * sizeof(*values->pid)),
	     *ntid = realloc(values->tid, nthreads_max * sizeof(*values->tid)),
	     *nvalue = realloc(values->value, nthreads_max * sizeof(*values->value));

	if (!npid || !ntid || !nvalue)
		goto out_err;

	values->threads_max = nthreads_max;
	values->pid = npid;
	values->tid = ntid;
	values->value = nvalue;
	return 0;
out_err:
	free(npid);
	free(ntid);
	free(nvalue);
	pr_debug("failed to enlarge read_values threads arrays");
	return -ENOMEM;
}

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) {
		i = perf_read_values__enlarge_threads(values);
		if (i < 0)
			return i;
	}

	i = values->threads;

	values->value[i] = calloc(values->counters_max, sizeof(**values->value));
	if (!values->value[i]) {
		pr_debug("failed to allocate read_values counters array");
		return -ENOMEM;
	}
	values->pid[i] = pid;
	values->tid[i] = tid;
	values->threads = i + 1;

	return i;
}

static int perf_read_values__enlarge_counters(struct perf_read_values *values)
{
	int counters_max = values->counters_max * 2;
	struct evsel **new_counters = realloc(values->counters,
					     counters_max * sizeof(*values->counters));

	if (!new_counters) {
		pr_debug("failed to enlarge read_values counters array");
		goto out_enomem;
	}

	for (int i = 0; i < values->threads; i++) {
		u64 *value = realloc(values->value[i], counters_max * sizeof(**values->value));

		if (!value) {
			pr_debug("failed to enlarge read_values ->values array");
			goto out_free_counters;
		}

		for (int j = values->counters_max; j < counters_max; j++)
			value[j] = 0;

		values->value[i] = value;
	}

	values->counters_max = counters_max;
	values->counters = new_counters;

	return 0;
out_free_counters:
	free(new_counters);
out_enomem:
	return -ENOMEM;
}

static int perf_read_values__findnew_counter(struct perf_read_values *values,
					     struct evsel *evsel)
{
	int i;

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

	if (values->num_counters == values->counters_max) {
		int err = perf_read_values__enlarge_counters(values);

		if (err)
			return err;
	}

	i = values->num_counters++;
	values->counters[i] = evsel;

	return i;
}

int perf_read_values_add_value(struct perf_read_values *values,
				u32 pid, u32 tid,
				struct evsel *evsel, u64 value)
{
	int tindex, cindex;

	tindex = perf_read_values__findnew_thread(values, pid, tid);
	if (tindex < 0)
		return tindex;
	cindex = perf_read_values__findnew_counter(values, evsel);
	if (cindex < 0)
		return cindex;

	values->value[tindex][cindex] += value;
	return 0;
}

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->num_counters * sizeof(*counterwidth));
	if (!counterwidth) {
		fprintf(fp, "INTERNAL ERROR: Failed to allocate counterwidth array\n");
		return;
	}
	tidwidth = 3;
	pidwidth = 3;
	for (j = 0; j < values->num_counters; j++)
		counterwidth[j] = strlen(evsel__name(values->counters[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->num_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->num_counters; j++)
		fprintf(fp, "  %*s", counterwidth[j], evsel__name(values->counters[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->num_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->num_counters; j++) {
		width = strlen(evsel__name(values->counters[j]));
		if (width > namewidth)
			namewidth = width;
		width = snprintf(NULL, 0, "%x", values->counters[j]->core.idx);
		if (width > rawwidth)
			rawwidth = width;
	}
	for (i = 0; i < values->threads; i++) {
		for (j = 0; j < values->num_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->num_counters; j++)
			fprintf(fp, "  %*d  %*d  %*s  %*x  %*" PRIu64,
				pidwidth, values->pid[i],
				tidwidth, values->tid[i],
				namewidth, evsel__name(values->counters[j]),
				rawwidth, values->counters[j]->core.idx,
				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);
}
