// 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 inline u64 timeval2usec(struct timeval *tv)
{
	return tv->tv_sec * USEC_PER_SEC + tv->tv_usec;
}

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;
	struct evlist *evlist = evlist__new();
	int ret;

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

	parse_events_error__init(&err);
	ret = parse_events(evlist, evstr, &err);
	if (ret) {
		parse_events_error__print(&err, evstr);
		parse_events_error__exit(&err);
		pr_err("Run 'perf list' for a list of valid events\n");
		ret = 1;
		goto out_delete_evlist;
	}
	parse_events_error__exit(&err);
	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 = timeval2usec(&diff);
		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;
}
