// SPDX-License-Identifier: GPL-2.0
#include <inttypes.h>
#include "perf.h"
#include "util/debug.h"
#include "util/map.h"
#include "util/symbol.h"
#include "util/sort.h"
#include "util/evsel.h"
#include "util/evlist.h"
#include "util/machine.h"
#include "util/thread.h"
#include "tests/hists_common.h"
#include <linux/kernel.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);
	}
}
