// SPDX-License-Identifier: GPL-2.0
#include <linux/compiler.h>
#include <stdio.h>
#include <string.h>
#include "builtin.h"
#include "perf.h"
#include "debug.h"
#include <subcmd/parse-options.h>
#include "data-convert.h"

typedef int (*data_cmd_fn_t)(int argc, const char **argv);

struct data_cmd {
	const char	*name;
	const char	*summary;
	data_cmd_fn_t	fn;
};

static struct data_cmd data_cmds[];

#define for_each_cmd(cmd) \
	for (cmd = data_cmds; cmd && cmd->name; cmd++)

static const struct option data_options[] = {
	OPT_END()
};

static const char * const data_subcommands[] = { "convert", NULL };

static const char *data_usage[] = {
	"perf data [<common options>] <command> [<options>]",
	NULL
};

static void print_usage(void)
{
	struct data_cmd *cmd;

	printf("Usage:\n");
	printf("\t%s\n\n", data_usage[0]);
	printf("\tAvailable commands:\n");

	for_each_cmd(cmd) {
		printf("\t %s\t- %s\n", cmd->name, cmd->summary);
	}

	printf("\n");
}

static const char * const data_convert_usage[] = {
	"perf data convert [<options>]",
	NULL
};

static int cmd_data_convert(int argc, const char **argv)
{
	const char *to_json = NULL;
	const char *to_ctf = NULL;
	struct perf_data_convert_opts opts = {
		.force = false,
		.all = false,
	};
	const struct option options[] = {
		OPT_INCR('v', "verbose", &verbose, "be more verbose"),
		OPT_STRING('i', "input", &input_name, "file", "input file name"),
		OPT_STRING(0, "to-json", &to_json, NULL, "Convert to JSON format"),
#ifdef HAVE_LIBBABELTRACE_SUPPORT
		OPT_STRING(0, "to-ctf", &to_ctf, NULL, "Convert to CTF format"),
		OPT_BOOLEAN(0, "tod", &opts.tod, "Convert time to wall clock time"),
#endif
		OPT_BOOLEAN('f', "force", &opts.force, "don't complain, do it"),
		OPT_BOOLEAN(0, "all", &opts.all, "Convert all events"),
		OPT_END()
	};

	argc = parse_options(argc, argv, options,
			     data_convert_usage, 0);
	if (argc) {
		usage_with_options(data_convert_usage, options);
		return -1;
	}

	if (to_json && to_ctf) {
		pr_err("You cannot specify both --to-ctf and --to-json.\n");
		return -1;
	}
	if (!to_json && !to_ctf) {
		pr_err("You must specify one of --to-ctf or --to-json.\n");
		return -1;
	}

	if (to_json)
		return bt_convert__perf2json(input_name, to_json, &opts);

	if (to_ctf) {
#ifdef HAVE_LIBBABELTRACE_SUPPORT
		return bt_convert__perf2ctf(input_name, to_ctf, &opts);
#else
		pr_err("The libbabeltrace support is not compiled in. perf should be "
		       "compiled with environment variables LIBBABELTRACE=1 and "
		       "LIBBABELTRACE_DIR=/path/to/libbabeltrace/\n");
		return -1;
#endif
	}

	return 0;
}

static struct data_cmd data_cmds[] = {
	{ "convert", "converts data file between formats", cmd_data_convert },
	{ .name = NULL, },
};

int cmd_data(int argc, const char **argv)
{
	struct data_cmd *cmd;
	const char *cmdstr;

	/* No command specified. */
	if (argc < 2)
		goto usage;

	argc = parse_options_subcommand(argc, argv, data_options, data_subcommands, data_usage,
			     PARSE_OPT_STOP_AT_NON_OPTION);
	if (argc < 1)
		goto usage;

	cmdstr = argv[0];

	for_each_cmd(cmd) {
		if (strcmp(cmd->name, cmdstr))
			continue;

		return cmd->fn(argc, argv);
	}

	pr_err("Unknown command: %s\n", cmdstr);
usage:
	print_usage();
	return -1;
}
