// SPDX-License-Identifier: GPL-2.0
#include <inttypes.h>
#include "util/debug.h"
#include "util/dso.h"
#include "util/event.h" // struct perf_sample
#include "util/map.h"
#include "util/symbol.h"
#include "util/sort.h"
#include "util/evsel.h"
#include "util/machine.h"
#include "util/thread.h"
#include "tests/hists_common.h"
#include <linux/kernel.h>
#include <linux/perf_event.h>

static struct {
	u32 pid;
	const char *comm;
} fake_threads[] = {
	{ FAKE_PID_PERF1, "perf" },
	{ FAKE_PID_PERF2, "perf" },
	{ FAKE_PID_BASH,  "bash" },
};

static struct {
	u32 pid;
	u64 start;
	const char *filename;
} fake_mmap_info[] = {
	{ FAKE_PID_PERF1, FAKE_MAP_PERF,   "perf" },
	{ FAKE_PID_PERF1, FAKE_MAP_LIBC,   "libc" },
	{ FAKE_PID_PERF1, FAKE_MAP_KERNEL, "[kernel]" },
	{ FAKE_PID_PERF2, FAKE_MAP_PERF,   "perf" },
	{ FAKE_PID_PERF2, FAKE_MAP_LIBC,   "libc" },
	{ FAKE_PID_PERF2, FAKE_MAP_KERNEL, "[kernel]" },
	{ FAKE_PID_BASH,  FAKE_MAP_BASH,   "bash" },
	{ FAKE_PID_BASH,  FAKE_MAP_LIBC,   "libc" },
	{ FAKE_PID_BASH,  FAKE_MAP_KERNEL, "[kernel]" },
};

struct fake_sym {
	u64 start;
	u64 length;
	const char *name;
};

static struct fake_sym perf_syms[] = {
	{ FAKE_SYM_OFFSET1, FAKE_SYM_LENGTH, "main" },
	{ FAKE_SYM_OFFSET2, FAKE_SYM_LENGTH, "run_command" },
	{ FAKE_SYM_OFFSET3, FAKE_SYM_LENGTH, "cmd_record" },
};

static struct fake_sym bash_syms[] = {
	{ FAKE_SYM_OFFSET1, FAKE_SYM_LENGTH, "main" },
	{ FAKE_SYM_OFFSET2, FAKE_SYM_LENGTH, "xmalloc" },
	{ FAKE_SYM_OFFSET3, FAKE_SYM_LENGTH, "xfree" },
};

static struct fake_sym libc_syms[] = {
	{ 700, 100, "malloc" },
	{ 800, 100, "free" },
	{ 900, 100, "realloc" },
	{ FAKE_SYM_OFFSET1, FAKE_SYM_LENGTH, "malloc" },
	{ FAKE_SYM_OFFSET2, FAKE_SYM_LENGTH, "free" },
	{ FAKE_SYM_OFFSET3, FAKE_SYM_LENGTH, "realloc" },
};

static struct fake_sym kernel_syms[] = {
	{ FAKE_SYM_OFFSET1, FAKE_SYM_LENGTH, "schedule" },
	{ FAKE_SYM_OFFSET2, FAKE_SYM_LENGTH, "page_fault" },
	{ FAKE_SYM_OFFSET3, FAKE_SYM_LENGTH, "sys_perf_event_open" },
};

static struct {
	const char *dso_name;
	struct fake_sym *syms;
	size_t nr_syms;
} fake_symbols[] = {
	{ "perf", perf_syms, ARRAY_SIZE(perf_syms) },
	{ "bash", bash_syms, ARRAY_SIZE(bash_syms) },
	{ "libc", libc_syms, ARRAY_SIZE(libc_syms) },
	{ "[kernel]", kernel_syms, ARRAY_SIZE(kernel_syms) },
};

struct machine *setup_fake_machine(struct machines *machines)
{
	struct machine *machine = machines__find(machines, HOST_KERNEL_ID);
	size_t i;

	if (machine == NULL) {
		pr_debug("Not enough memory for machine setup\n");
		return NULL;
	}

	for (i = 0; i < ARRAY_SIZE(fake_threads); i++) {
		struct thread *thread;

		thread = machine__findnew_thread(machine, fake_threads[i].pid,
						 fake_threads[i].pid);
		if (thread == NULL)
			goto out;

		thread__set_comm(thread, fake_threads[i].comm, 0);
		thread__put(thread);
	}

	for (i = 0; i < ARRAY_SIZE(fake_mmap_info); i++) {
		struct perf_sample sample = {
			.cpumode = PERF_RECORD_MISC_USER,
		};
		union perf_event fake_mmap_event = {
			.mmap = {
				.pid = fake_mmap_info[i].pid,
				.tid = fake_mmap_info[i].pid,
				.start = fake_mmap_info[i].start,
				.len = FAKE_MAP_LENGTH,
				.pgoff = 0ULL,
			},
		};

		strcpy(fake_mmap_event.mmap.filename,
		       fake_mmap_info[i].filename);

		machine__process_mmap_event(machine, &fake_mmap_event, &sample);
	}

	for (i = 0; i < ARRAY_SIZE(fake_symbols); i++) {
		size_t k;
		struct dso *dso;

		dso = machine__findnew_dso(machine, fake_symbols[i].dso_name);
		if (dso == NULL)
			goto out;

		/* emulate dso__load() */
		dso__set_loaded(dso);

		for (k = 0; k < fake_symbols[i].nr_syms; k++) {
			struct symbol *sym;
			struct fake_sym *fsym = &fake_symbols[i].syms[k];

			sym = symbol__new(fsym->start, fsym->length,
					  STB_GLOBAL, STT_FUNC, fsym->name);
			if (sym == NULL) {
				dso__put(dso);
				goto out;
			}

			symbols__insert(dso__symbols(dso), sym);
		}

		dso__put(dso);
	}

	return machine;

out:
	pr_debug("Not enough memory for machine setup\n");
	machine__delete_threads(machine);
	return NULL;
}

void print_hists_in(struct hists *hists)
{
	int i = 0;
	struct rb_root_cached *root;
	struct rb_node *node;

	if (hists__has(hists, need_collapse))
		root = &hists->entries_collapsed;
	else
		root = hists->entries_in;

	pr_info("----- %s --------\n", __func__);
	node = rb_first_cached(root);
	while (node) {
		struct hist_entry *he;

		he = rb_entry(node, struct hist_entry, rb_node_in);

		if (!he->filtered) {
			struct dso *dso = map__dso(he->ms.map);

			pr_info("%2d: entry: %-8s [%-8s] %20s: period = %"PRIu64"\n",
				i, thread__comm_str(he->thread),
				dso__short_name(dso),
				he->ms.sym->name, he->stat.period);
		}

		i++;
		node = rb_next(node);
	}
}

void print_hists_out(struct hists *hists)
{
	int i = 0;
	struct rb_root_cached *root;
	struct rb_node *node;

	root = &hists->entries;

	pr_info("----- %s --------\n", __func__);
	node = rb_first_cached(root);
	while (node) {
		struct hist_entry *he;

		he = rb_entry(node, struct hist_entry, rb_node);

		if (!he->filtered) {
			struct dso *dso = map__dso(he->ms.map);

			pr_info("%2d: entry: %8s:%5d [%-8s] %20s: period = %"PRIu64"/%"PRIu64"\n",
				i, thread__comm_str(he->thread), thread__tid(he->thread),
				dso__short_name(dso),
				he->ms.sym->name, he->stat.period,
				he->stat_acc ? he->stat_acc->period : 0);
		}

		i++;
		node = rb_next(node);
	}
}
