/* SPDX-License-Identifier: GPL-2.0 */
#include <errno.h>
#include <inttypes.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#include "dwarf-regs.h" /* for EM_HOST */
#include "trace/beauty/syscalltbl.h"
#include "util/cgroup.h"
#include "util/hashmap.h"
#include "util/trace.h"
#include "util/util.h"
#include <bpf/bpf.h>
#include <linux/rbtree.h>
#include <linux/time64.h>
#include <tools/libc_compat.h> /* reallocarray */

#include "bpf_skel/syscall_summary.h"
#include "bpf_skel/syscall_summary.skel.h"


static struct syscall_summary_bpf *skel;
static struct rb_root cgroups = RB_ROOT;

int trace_prepare_bpf_summary(enum trace_summary_mode mode)
{
	skel = syscall_summary_bpf__open();
	if (skel == NULL) {
		fprintf(stderr, "failed to open syscall summary bpf skeleton\n");
		return -1;
	}

	if (mode == SUMMARY__BY_THREAD)
		skel->rodata->aggr_mode = SYSCALL_AGGR_THREAD;
	else if (mode == SUMMARY__BY_CGROUP)
		skel->rodata->aggr_mode = SYSCALL_AGGR_CGROUP;
	else
		skel->rodata->aggr_mode = SYSCALL_AGGR_CPU;

	if (cgroup_is_v2("perf_event") > 0)
		skel->rodata->use_cgroup_v2 = 1;

	if (syscall_summary_bpf__load(skel) < 0) {
		fprintf(stderr, "failed to load syscall summary bpf skeleton\n");
		return -1;
	}

	if (syscall_summary_bpf__attach(skel) < 0) {
		fprintf(stderr, "failed to attach syscall summary bpf skeleton\n");
		return -1;
	}

	if (mode == SUMMARY__BY_CGROUP)
		read_all_cgroups(&cgroups);

	return 0;
}

void trace_start_bpf_summary(void)
{
	skel->bss->enabled = 1;
}

void trace_end_bpf_summary(void)
{
	skel->bss->enabled = 0;
}

struct syscall_node {
	int syscall_nr;
	struct syscall_stats stats;
};

static double rel_stddev(struct syscall_stats *stat)
{
	double variance, average;

	if (stat->count < 2)
		return 0;

	average = (double)stat->total_time / stat->count;

	variance = stat->squared_sum;
	variance -= (stat->total_time * stat->total_time) / stat->count;
	variance /= stat->count - 1;

	return 100 * sqrt(variance / stat->count) / average;
}

/*
 * The syscall_data is to maintain syscall stats ordered by total time.
 * It supports different summary modes like per-thread or global.
 *
 * For per-thread stats, it uses two-level data strurcture -
 * syscall_data is keyed by TID and has an array of nodes which
 * represents each syscall for the thread.
 *
 * For global stats, it's still two-level technically but we don't need
 * per-cpu analysis so it's keyed by the syscall number to combine stats
 * from different CPUs.  And syscall_data always has a syscall_node so
 * it can effectively work as flat hierarchy.
 *
 * For per-cgroup stats, it uses two-level data structure like thread
 * syscall_data is keyed by CGROUP and has an array of node which
 * represents each syscall for the cgroup.
 */
struct syscall_data {
	u64 key; /* tid if AGGR_THREAD, syscall-nr if AGGR_CPU, cgroup if AGGR_CGROUP */
	int nr_events;
	int nr_nodes;
	u64 total_time;
	struct syscall_node *nodes;
};

static int datacmp(const void *a, const void *b)
{
	const struct syscall_data * const *sa = a;
	const struct syscall_data * const *sb = b;

	return (*sa)->total_time > (*sb)->total_time ? -1 : 1;
}

static int nodecmp(const void *a, const void *b)
{
	const struct syscall_node *na = a;
	const struct syscall_node *nb = b;

	return na->stats.total_time > nb->stats.total_time ? -1 : 1;
}

static size_t sc_node_hash(long key, void *ctx __maybe_unused)
{
	return key;
}

static bool sc_node_equal(long key1, long key2, void *ctx __maybe_unused)
{
	return key1 == key2;
}

static int print_common_stats(struct syscall_data *data, int max_summary, FILE *fp)
{
	int printed = 0;

	if (max_summary == 0 || max_summary > data->nr_nodes)
		max_summary = data->nr_nodes;

	for (int i = 0; i < max_summary; i++) {
		struct syscall_node *node = &data->nodes[i];
		struct syscall_stats *stat = &node->stats;
		double total = (double)(stat->total_time) / NSEC_PER_MSEC;
		double min = (double)(stat->min_time) / NSEC_PER_MSEC;
		double max = (double)(stat->max_time) / NSEC_PER_MSEC;
		double avg = total / stat->count;
		const char *name;

		/* TODO: support other ABIs */
		name = syscalltbl__name(EM_HOST, node->syscall_nr);
		if (name)
			printed += fprintf(fp, "   %-15s", name);
		else
			printed += fprintf(fp, "   syscall:%-7d", node->syscall_nr);

		printed += fprintf(fp, " %8u %6u %9.3f %9.3f %9.3f %9.3f %9.2f%%\n",
				   stat->count, stat->error, total, min, avg, max,
				   rel_stddev(stat));
	}
	return printed;
}

static int update_thread_stats(struct hashmap *hash, struct syscall_key *map_key,
			       struct syscall_stats *map_data)
{
	struct syscall_data *data;
	struct syscall_node *nodes;

	if (!hashmap__find(hash, map_key->cpu_or_tid, &data)) {
		data = zalloc(sizeof(*data));
		if (data == NULL)
			return -ENOMEM;

		data->key = map_key->cpu_or_tid;
		if (hashmap__add(hash, data->key, data) < 0) {
			free(data);
			return -ENOMEM;
		}
	}

	/* update thread total stats */
	data->nr_events += map_data->count;
	data->total_time += map_data->total_time;

	nodes = reallocarray(data->nodes, data->nr_nodes + 1, sizeof(*nodes));
	if (nodes == NULL)
		return -ENOMEM;

	data->nodes = nodes;
	nodes = &data->nodes[data->nr_nodes++];
	nodes->syscall_nr = map_key->nr;

	/* each thread has an entry for each syscall, just use the stat */
	memcpy(&nodes->stats, map_data, sizeof(*map_data));
	return 0;
}

static int print_thread_stat(struct syscall_data *data, int max_summary, FILE *fp)
{
	int printed = 0;

	qsort(data->nodes, data->nr_nodes, sizeof(*data->nodes), nodecmp);

	printed += fprintf(fp, " thread (%d), ", (int)data->key);
	printed += fprintf(fp, "%d events\n\n", data->nr_events);

	printed += fprintf(fp, "   syscall            calls  errors  total       min       avg       max       stddev\n");
	printed += fprintf(fp, "                                     (msec)    (msec)    (msec)    (msec)        (%%)\n");
	printed += fprintf(fp, "   --------------- --------  ------ -------- --------- --------- ---------     ------\n");

	printed += print_common_stats(data, max_summary, fp);
	printed += fprintf(fp, "\n\n");

	return printed;
}

static int print_thread_stats(struct syscall_data **data, int nr_data, int max_summary, FILE *fp)
{
	int printed = 0;

	for (int i = 0; i < nr_data; i++)
		printed += print_thread_stat(data[i], max_summary, fp);

	return printed;
}

static int update_total_stats(struct hashmap *hash, struct syscall_key *map_key,
			      struct syscall_stats *map_data)
{
	struct syscall_data *data;
	struct syscall_stats *stat;

	if (!hashmap__find(hash, map_key->nr, &data)) {
		data = zalloc(sizeof(*data));
		if (data == NULL)
			return -ENOMEM;

		data->nodes = zalloc(sizeof(*data->nodes));
		if (data->nodes == NULL) {
			free(data);
			return -ENOMEM;
		}

		data->nr_nodes = 1;
		data->key = map_key->nr;
		data->nodes->syscall_nr = data->key;

		if (hashmap__add(hash, data->key, data) < 0) {
			free(data->nodes);
			free(data);
			return -ENOMEM;
		}
	}

	/* update total stats for this syscall */
	data->nr_events += map_data->count;
	data->total_time += map_data->total_time;

	/* This is sum of the same syscall from different CPUs */
	stat = &data->nodes->stats;

	stat->total_time += map_data->total_time;
	stat->squared_sum += map_data->squared_sum;
	stat->count += map_data->count;
	stat->error += map_data->error;

	if (stat->max_time < map_data->max_time)
		stat->max_time = map_data->max_time;
	if (stat->min_time > map_data->min_time || stat->min_time == 0)
		stat->min_time = map_data->min_time;

	return 0;
}

static int print_total_stats(struct syscall_data **data, int nr_data, int max_summary, FILE *fp)
{
	int printed = 0;
	int nr_events = 0;

	for (int i = 0; i < nr_data; i++)
		nr_events += data[i]->nr_events;

	printed += fprintf(fp, " total, %d events\n\n", nr_events);

	printed += fprintf(fp, "   syscall            calls  errors  total       min       avg       max       stddev\n");
	printed += fprintf(fp, "                                     (msec)    (msec)    (msec)    (msec)        (%%)\n");
	printed += fprintf(fp, "   --------------- --------  ------ -------- --------- --------- ---------     ------\n");

	if (max_summary == 0 || max_summary > nr_data)
		max_summary = nr_data;

	for (int i = 0; i < max_summary; i++)
		printed += print_common_stats(data[i], max_summary, fp);

	printed += fprintf(fp, "\n\n");
	return printed;
}

static int update_cgroup_stats(struct hashmap *hash, struct syscall_key *map_key,
			       struct syscall_stats *map_data)
{
	struct syscall_data *data;
	struct syscall_node *nodes;

	if (!hashmap__find(hash, map_key->cgroup, &data)) {
		data = zalloc(sizeof(*data));
		if (data == NULL)
			return -ENOMEM;

		data->key = map_key->cgroup;
		if (hashmap__add(hash, data->key, data) < 0) {
			free(data);
			return -ENOMEM;
		}
	}

	/* update thread total stats */
	data->nr_events += map_data->count;
	data->total_time += map_data->total_time;

	nodes = reallocarray(data->nodes, data->nr_nodes + 1, sizeof(*nodes));
	if (nodes == NULL)
		return -ENOMEM;

	data->nodes = nodes;
	nodes = &data->nodes[data->nr_nodes++];
	nodes->syscall_nr = map_key->nr;

	/* each thread has an entry for each syscall, just use the stat */
	memcpy(&nodes->stats, map_data, sizeof(*map_data));
	return 0;
}

static int print_cgroup_stat(struct syscall_data *data, int max_summary, FILE *fp)
{
	int printed = 0;
	struct cgroup *cgrp = __cgroup__find(&cgroups, data->key);

	qsort(data->nodes, data->nr_nodes, sizeof(*data->nodes), nodecmp);

	if (cgrp)
		printed += fprintf(fp, " cgroup %s,", cgrp->name);
	else
		printed += fprintf(fp, " cgroup id:%lu,", (unsigned long)data->key);

	printed += fprintf(fp, " %d events\n\n", data->nr_events);

	printed += fprintf(fp, "   syscall            calls  errors  total       min       avg       max       stddev\n");
	printed += fprintf(fp, "                                     (msec)    (msec)    (msec)    (msec)        (%%)\n");
	printed += fprintf(fp, "   --------------- --------  ------ -------- --------- --------- ---------     ------\n");

	printed += print_common_stats(data, max_summary, fp);
	printed += fprintf(fp, "\n\n");

	return printed;
}

static int print_cgroup_stats(struct syscall_data **data, int nr_data, int max_summary, FILE *fp)
{
	int printed = 0;

	for (int i = 0; i < nr_data; i++)
		printed += print_cgroup_stat(data[i], max_summary, fp);

	return printed;
}

int trace_print_bpf_summary(FILE *fp, int max_summary)
{
	struct bpf_map *map = skel->maps.syscall_stats_map;
	struct syscall_key *prev_key, key;
	struct syscall_data **data = NULL;
	struct hashmap schash;
	struct hashmap_entry *entry;
	int nr_data = 0;
	int printed = 0;
	int i;
	size_t bkt;

	hashmap__init(&schash, sc_node_hash, sc_node_equal, /*ctx=*/NULL);

	printed = fprintf(fp, "\n Summary of events:\n\n");

	/* get stats from the bpf map */
	prev_key = NULL;
	while (!bpf_map__get_next_key(map, prev_key, &key, sizeof(key))) {
		struct syscall_stats stat;

		if (!bpf_map__lookup_elem(map, &key, sizeof(key), &stat, sizeof(stat), 0)) {
			switch (skel->rodata->aggr_mode) {
			case SYSCALL_AGGR_THREAD:
				update_thread_stats(&schash, &key, &stat);
				break;
			case SYSCALL_AGGR_CPU:
				update_total_stats(&schash, &key, &stat);
				break;
			case SYSCALL_AGGR_CGROUP:
				update_cgroup_stats(&schash, &key, &stat);
				break;
			default:
				break;
			}
		}

		prev_key = &key;
	}

	nr_data = hashmap__size(&schash);
	data = calloc(nr_data, sizeof(*data));
	if (data == NULL)
		goto out;

	i = 0;
	hashmap__for_each_entry(&schash, entry, bkt)
		data[i++] = entry->pvalue;

	qsort(data, nr_data, sizeof(*data), datacmp);

	switch (skel->rodata->aggr_mode) {
	case SYSCALL_AGGR_THREAD:
		printed += print_thread_stats(data, nr_data, max_summary, fp);
		break;
	case SYSCALL_AGGR_CPU:
		printed += print_total_stats(data, nr_data, max_summary, fp);
		break;
	case SYSCALL_AGGR_CGROUP:
		printed += print_cgroup_stats(data, nr_data, max_summary, fp);
		break;
	default:
		break;
	}

	for (i = 0; i < nr_data && data; i++) {
		free(data[i]->nodes);
		free(data[i]);
	}
	free(data);

out:
	hashmap__clear(&schash);
	return printed;
}

void trace_cleanup_bpf_summary(void)
{
	if (!RB_EMPTY_ROOT(&cgroups)) {
		struct cgroup *cgrp, *tmp;

		rbtree_postorder_for_each_entry_safe(cgrp, tmp, &cgroups, node)
			cgroup__put(cgrp);

		cgroups = RB_ROOT;
	}

	syscall_summary_bpf__destroy(skel);
}
