// SPDX-License-Identifier: GPL-2.0
#include <elf.h>
#include <inttypes.h>
#include <sys/ttydefaults.h>
#include <stdlib.h>
#include <string.h>
#include <linux/bitops.h>
#include "../../util/debug.h"
#include "../../util/map.h"
#include "../../util/dso.h"
#include "../../util/symbol.h"
#include "../browser.h"
#include "../helpline.h"
#include "../keysyms.h"
#include "map.h"

#include <linux/ctype.h>

struct map_browser {
	struct ui_browser b;
	struct map	  *map;
	u8		  addrlen;
};

static void map_browser__write(struct ui_browser *browser, void *nd, int row)
{
	struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
	struct map_browser *mb = container_of(browser, struct map_browser, b);
	bool current_entry = ui_browser__is_current_entry(browser, row);
	int width;

	ui_browser__set_percent_color(browser, 0, current_entry);
	ui_browser__printf(browser, "%*" PRIx64 " %*" PRIx64 " %c ",
			   mb->addrlen, sym->start, mb->addrlen, sym->end,
			   sym->binding == STB_GLOBAL ? 'g' :
				sym->binding == STB_LOCAL  ? 'l' : 'w');
	width = browser->width - ((mb->addrlen * 2) + 4);
	if (width > 0)
		ui_browser__write_nstring(browser, sym->name, width);
}

/* FIXME uber-kludgy, see comment on cmd_report... */
static u32 *symbol__browser_index(struct symbol *browser)
{
	return ((void *)browser) - sizeof(struct rb_node) - sizeof(u32);
}

static int map_browser__search(struct map_browser *browser)
{
	char target[512];
	struct symbol *sym;
	int err = ui_browser__input_window("Search by name/addr",
					   "Prefix with 0x to search by address",
					   target, "ENTER: OK, ESC: Cancel", 0);
	if (err != K_ENTER)
		return -1;

	if (target[0] == '0' && tolower(target[1]) == 'x') {
		u64 addr = strtoull(target, NULL, 16);
		sym = map__find_symbol(browser->map, addr);
	} else
		sym = map__find_symbol_by_name(browser->map, target);

	if (sym != NULL) {
		u32 *idx = symbol__browser_index(sym);

		browser->b.top = &sym->rb_node;
		browser->b.index = browser->b.top_idx = *idx;
	} else
		ui_helpline__fpush("%s not found!", target);

	return 0;
}

static int map_browser__run(struct map_browser *browser)
{
	int key;

	if (ui_browser__show(&browser->b, map__dso(browser->map)->long_name,
			     "Press ESC to exit, %s / to search",
			     verbose > 0 ? "" : "restart with -v to use") < 0)
		return -1;

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

		switch (key) {
		case '/':
			if (verbose > 0)
				map_browser__search(browser);
		default:
			break;
                case K_LEFT:
                case K_ESC:
                case 'q':
                case CTRL('c'):
                        goto out;
		}
	}
out:
	ui_browser__hide(&browser->b);
	return key;
}

int map__browse(struct map *map)
{
	struct map_browser mb = {
		.b = {
			.entries = &map__dso(map)->symbols,
			.refresh = ui_browser__rb_tree_refresh,
			.seek	 = ui_browser__rb_tree_seek,
			.write	 = map_browser__write,
		},
		.map = map,
	};
	struct rb_node *nd;
	char tmp[BITS_PER_LONG / 4];
	u64 maxaddr = 0;

	for (nd = rb_first(mb.b.entries); nd; nd = rb_next(nd)) {
		struct symbol *pos = rb_entry(nd, struct symbol, rb_node);

		if (maxaddr < pos->end)
			maxaddr = pos->end;
		if (verbose > 0) {
			u32 *idx = symbol__browser_index(pos);
			*idx = mb.b.nr_entries;
		}
		++mb.b.nr_entries;
	}

	mb.addrlen = snprintf(tmp, sizeof(tmp), "%" PRIx64, maxaddr);
	return map_browser__run(&mb);
}
