// SPDX-License-Identifier: GPL-2.0
#include <elf.h>
#include <inttypes.h>
#include <sys/ttydefaults.h>
#include <string.h>
#include "../../util/sort.h"
#include "../../util/util.h"
#include "../../util/hist.h"
#include "../../util/debug.h"
#include "../../util/symbol.h"
#include "../browser.h"
#include "../helpline.h"
#include "../libslang.h"

/* 2048 lines should be enough for a script output */
#define MAX_LINES		2048

/* 160 bytes for one output line */
#define AVERAGE_LINE_LEN	160

struct script_line {
	struct list_head node;
	char line[AVERAGE_LINE_LEN];
};

struct perf_script_browser {
	struct ui_browser b;
	struct list_head entries;
	const char *script_name;
	int nr_lines;
};

#define SCRIPT_NAMELEN	128
#define SCRIPT_MAX_NO	64
/*
 * Usually the full path for a script is:
 *	/home/username/libexec/perf-core/scripts/python/xxx.py
 *	/home/username/libexec/perf-core/scripts/perl/xxx.pl
 * So 256 should be long enough to contain the full path.
 */
#define SCRIPT_FULLPATH_LEN	256

/*
 * When success, will copy the full path of the selected script
 * into  the buffer pointed by script_name, and return 0.
 * Return -1 on failure.
 */
static int list_scripts(char *script_name)
{
	char *buf, *names[SCRIPT_MAX_NO], *paths[SCRIPT_MAX_NO];
	int i, num, choice, ret = -1;

	/* Preset the script name to SCRIPT_NAMELEN */
	buf = malloc(SCRIPT_MAX_NO * (SCRIPT_NAMELEN + SCRIPT_FULLPATH_LEN));
	if (!buf)
		return ret;

	for (i = 0; i < SCRIPT_MAX_NO; i++) {
		names[i] = buf + i * (SCRIPT_NAMELEN + SCRIPT_FULLPATH_LEN);
		paths[i] = names[i] + SCRIPT_NAMELEN;
	}

	num = find_scripts(names, paths);
	if (num > 0) {
		choice = ui__popup_menu(num, names);
		if (choice < num && choice >= 0) {
			strcpy(script_name, paths[choice]);
			ret = 0;
		}
	}

	free(buf);
	return ret;
}

static void script_browser__write(struct ui_browser *browser,
				   void *entry, int row)
{
	struct script_line *sline = list_entry(entry, struct script_line, node);
	bool current_entry = ui_browser__is_current_entry(browser, row);

	ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
						       HE_COLORSET_NORMAL);

	ui_browser__write_nstring(browser, sline->line, browser->width);
}

static int script_browser__run(struct perf_script_browser *browser)
{
	int key;

	if (ui_browser__show(&browser->b, browser->script_name,
			     "Press ESC to exit") < 0)
		return -1;

	while (1) {
		key = ui_browser__run(&browser->b, 0);

		/* We can add some special key handling here if needed */
		break;
	}

	ui_browser__hide(&browser->b);
	return key;
}


int script_browse(const char *script_opt)
{
	char cmd[SCRIPT_FULLPATH_LEN*2], script_name[SCRIPT_FULLPATH_LEN];
	char *line = NULL;
	size_t len = 0;
	ssize_t retlen;
	int ret = -1, nr_entries = 0;
	FILE *fp;
	void *buf;
	struct script_line *sline;

	struct perf_script_browser script = {
		.b = {
			.refresh    = ui_browser__list_head_refresh,
			.seek	    = ui_browser__list_head_seek,
			.write	    = script_browser__write,
		},
		.script_name = script_name,
	};

	INIT_LIST_HEAD(&script.entries);

	/* Save each line of the output in one struct script_line object. */
	buf = zalloc((sizeof(*sline)) * MAX_LINES);
	if (!buf)
		return -1;
	sline = buf;

	memset(script_name, 0, SCRIPT_FULLPATH_LEN);
	if (list_scripts(script_name))
		goto exit;

	sprintf(cmd, "perf script -s %s ", script_name);

	if (script_opt)
		strcat(cmd, script_opt);

	if (input_name) {
		strcat(cmd, " -i ");
		strcat(cmd, input_name);
	}

	strcat(cmd, " 2>&1");

	fp = popen(cmd, "r");
	if (!fp)
		goto exit;

	while ((retlen = getline(&line, &len, fp)) != -1) {
		strncpy(sline->line, line, AVERAGE_LINE_LEN);

		/* If one output line is very large, just cut it short */
		if (retlen >= AVERAGE_LINE_LEN) {
			sline->line[AVERAGE_LINE_LEN - 1] = '\0';
			sline->line[AVERAGE_LINE_LEN - 2] = '\n';
		}
		list_add_tail(&sline->node, &script.entries);

		if (script.b.width < retlen)
			script.b.width = retlen;

		if (nr_entries++ >= MAX_LINES - 1)
			break;
		sline++;
	}

	if (script.b.width > AVERAGE_LINE_LEN)
		script.b.width = AVERAGE_LINE_LEN;

	free(line);
	pclose(fp);

	script.nr_lines = nr_entries;
	script.b.nr_entries = nr_entries;
	script.b.entries = &script.entries;

	ret = script_browser__run(&script);
exit:
	free(buf);
	return ret;
}
