// 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, 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) {
			pr_info("%2d: entry: %-8s [%-8s] %20s: period = %"PRIu64"\n",
				i, thread__comm_str(he->thread),
				he->ms.map->dso->short_name,
				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) {
			pr_info("%2d: entry: %8s:%5d [%-8s] %20s: period = %"PRIu64"/%"PRIu64"\n",
				i, thread__comm_str(he->thread), he->thread->tid,
				he->ms.map->dso->short_name,
				he->ms.sym->name, he->stat.period,
				he->stat_acc ? he->stat_acc->period : 0);
		}

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