// SPDX-License-Identifier: GPL-2.0
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "bench.h"
#include "../util/debug.h"
#include "../util/stat.h"
#include "../util/evlist.h"
#include "../util/evsel.h"
#include "../util/strbuf.h"
#include "../util/record.h"
#include "../util/parse-events.h"
#include "internal/threadmap.h"
#include "internal/cpumap.h"
#include <linux/perf_event.h>
#include <linux/kernel.h>
#include <linux/time64.h>
#include <linux/string.h>
#include <subcmd/parse-options.h>

#define MMAP_FLUSH_DEFAULT 1

static int iterations = 100;
static int nr_events = 1;
static const char *event_string = "dummy";

static struct record_opts opts = {
	.sample_time	     = true,
	.mmap_pages	     = UINT_MAX,
	.user_freq	     = UINT_MAX,
	.user_interval	     = ULLONG_MAX,
	.freq		     = 4000,
	.target		     = {
		.uses_mmap   = true,
		.default_per_cpu = true,
	},
	.mmap_flush          = MMAP_FLUSH_DEFAULT,
	.nr_threads_synthesize = 1,
	.ctl_fd              = -1,
	.ctl_fd_ack          = -1,
};

static const struct option options[] = {
	OPT_STRING('e', "event", &event_string, "event", "event selector. use 'perf list' to list available events"),
	OPT_INTEGER('n', "nr-events", &nr_events,
		     "number of dummy events to create (default 1). If used with -e, it clones those events n times (1 = no change)"),
	OPT_INTEGER('i', "iterations", &iterations, "Number of iterations used to compute average (default=100)"),
	OPT_BOOLEAN('a', "all-cpus", &opts.target.system_wide, "system-wide collection from all CPUs"),
	OPT_STRING('C', "cpu", &opts.target.cpu_list, "cpu", "list of cpus where to open events"),
	OPT_STRING('p', "pid", &opts.target.pid, "pid", "record events on existing process id"),
	OPT_STRING('t', "tid", &opts.target.tid, "tid", "record events on existing thread id"),
	OPT_STRING('u', "uid", &opts.target.uid_str, "user", "user to profile"),
	OPT_BOOLEAN(0, "per-thread", &opts.target.per_thread, "use per-thread mmaps"),
	OPT_END()
};

static const char *const bench_usage[] = {
	"perf bench internals evlist-open-close <options>",
	NULL
};

static int evlist__count_evsel_fds(struct evlist *evlist)
{
	struct evsel *evsel;
	int cnt = 0;

	evlist__for_each_entry(evlist, evsel)
		cnt += evsel->core.threads->nr * evsel->core.cpus->nr;

	return cnt;
}

static struct evlist *bench__create_evlist(char *evstr)
{
	struct parse_events_error err = { .idx = 0, };
	struct evlist *evlist = evlist__new();
	int ret;

	if (!evlist) {
		pr_err("Not enough memory to create evlist\n");
		return NULL;
	}

	ret = parse_events(evlist, evstr, &err);
	if (ret) {
		parse_events_print_error(&err, evstr);
		pr_err("Run 'perf list' for a list of valid events\n");
		ret = 1;
		goto out_delete_evlist;
	}

	ret = evlist__create_maps(evlist, &opts.target);
	if (ret < 0) {
		pr_err("Not enough memory to create thread/cpu maps\n");
		goto out_delete_evlist;
	}

	evlist__config(evlist, &opts, NULL);

	return evlist;

out_delete_evlist:
	evlist__delete(evlist);
	return NULL;
}

static int bench__do_evlist_open_close(struct evlist *evlist)
{
	char sbuf[STRERR_BUFSIZE];
	int err = evlist__open(evlist);

	if (err < 0) {
		pr_err("evlist__open: %s\n", str_error_r(errno, sbuf, sizeof(sbuf)));
		return err;
	}

	err = evlist__mmap(evlist, opts.mmap_pages);
	if (err < 0) {
		pr_err("evlist__mmap: %s\n", str_error_r(errno, sbuf, sizeof(sbuf)));
		return err;
	}

	evlist__enable(evlist);
	evlist__disable(evlist);
	evlist__munmap(evlist);
	evlist__close(evlist);

	return 0;
}

static int bench_evlist_open_close__run(char *evstr)
{
	// used to print statistics only
	struct evlist *evlist = bench__create_evlist(evstr);
	double time_average, time_stddev;
	struct timeval start, end, diff;
	struct stats time_stats;
	u64 runtime_us;
	int i, err;

	if (!evlist)
		return -ENOMEM;

	init_stats(&time_stats);

	printf("  Number of cpus:\t%d\n", evlist->core.cpus->nr);
	printf("  Number of threads:\t%d\n", evlist->core.threads->nr);
	printf("  Number of events:\t%d (%d fds)\n",
		evlist->core.nr_entries, evlist__count_evsel_fds(evlist));
	printf("  Number of iterations:\t%d\n", iterations);

	evlist__delete(evlist);

	for (i = 0; i < iterations; i++) {
		pr_debug("Started iteration %d\n", i);
		evlist = bench__create_evlist(evstr);
		if (!evlist)
			return -ENOMEM;

		gettimeofday(&start, NULL);
		err = bench__do_evlist_open_close(evlist);
		if (err) {
			evlist__delete(evlist);
			return err;
		}

		gettimeofday(&end, NULL);
		timersub(&end, &start, &diff);
		runtime_us = diff.tv_sec * USEC_PER_SEC + diff.tv_usec;
		update_stats(&time_stats, runtime_us);

		evlist__delete(evlist);
		pr_debug("Iteration %d took:\t%" PRIu64 "us\n", i, runtime_us);
	}

	time_average = avg_stats(&time_stats);
	time_stddev = stddev_stats(&time_stats);
	printf("  Average open-close took: %.3f usec (+- %.3f usec)\n", time_average, time_stddev);

	return 0;
}

static char *bench__repeat_event_string(const char *evstr, int n)
{
	char sbuf[STRERR_BUFSIZE];
	struct strbuf buf;
	int i, str_size = strlen(evstr),
	    final_size = str_size * n + n,
	    err = strbuf_init(&buf, final_size);

	if (err) {
		pr_err("strbuf_init: %s\n", str_error_r(err, sbuf, sizeof(sbuf)));
		goto out_error;
	}

	for (i = 0; i < n; i++) {
		err = strbuf_add(&buf, evstr, str_size);
		if (err) {
			pr_err("strbuf_add: %s\n", str_error_r(err, sbuf, sizeof(sbuf)));
			goto out_error;
		}

		err = strbuf_addch(&buf, i == n-1 ? '\0' : ',');
		if (err) {
			pr_err("strbuf_addch: %s\n", str_error_r(err, sbuf, sizeof(sbuf)));
			goto out_error;
		}
	}

	return strbuf_detach(&buf, NULL);

out_error:
	strbuf_release(&buf);
	return NULL;
}


int bench_evlist_open_close(int argc, const char **argv)
{
	char *evstr, errbuf[BUFSIZ];
	int err;

	argc = parse_options(argc, argv, options, bench_usage, 0);
	if (argc) {
		usage_with_options(bench_usage, options);
		exit(EXIT_FAILURE);
	}

	err = target__validate(&opts.target);
	if (err) {
		target__strerror(&opts.target, err, errbuf, sizeof(errbuf));
		pr_err("%s\n", errbuf);
		goto out;
	}

	err = target__parse_uid(&opts.target);
	if (err) {
		target__strerror(&opts.target, err, errbuf, sizeof(errbuf));
		pr_err("%s", errbuf);
		goto out;
	}

	/* Enable ignoring missing threads when -u/-p option is defined. */
	opts.ignore_missing_thread = opts.target.uid != UINT_MAX || opts.target.pid;

	evstr = bench__repeat_event_string(event_string, nr_events);
	if (!evstr) {
		err = -ENOMEM;
		goto out;
	}

	err = bench_evlist_open_close__run(evstr);

	free(evstr);
out:
	return err;
}
