/* SPDX-License-Identifier: GPL-2.0-only */

#include "coreinfo.h"
#include "endian.h"

#if CONFIG(MODULE_CBFS)

#define FILES_VISIBLE		19

#define HEADER_MAGIC		0x4F524243
#define HEADER_ADDR		0xfffffffc
#define LARCHIVE_MAGIC		0x455649484352414cLL	/* "LARCHIVE" */

#define COMPONENT_DELETED	0x00
#define COMPONENT_BOOTBLOCK	0x01
#define COMPONENT_CBFSHEADER	0x02
#define COMPONENT_STAGE		0x10
#define COMPONENT_SELF		0x20
#define COMPONENT_FIT		0x21
#define COMPONENT_OPTIONROM	0x30
#define COMPONENT_RAW		0x50
#define COMPONENT_MICROCODE	0x53
#define COMPONENT_CMOS_LAYOUT	0x1aa
#define COMPONENT_NULL		0xffffffff

struct cbheader {
	u32 magic;
	u32 version;
	u32 romsize;
	u32 bootblocksize;
	u32 align;
	u32 offset;
	u32 architecture;
	u32 pad[];
} __packed;

struct cbfile {
	u64 magic;
	u32 len;
	u32 type;
	u32 checksum;
	u32 offset;
	char filename[];
} __packed;

static int filecount = 0, selected = 0, start_row = 0;
static char **filenames;
static struct cbheader *header = NULL;

static struct cbfile *getfile(struct cbfile *f)
{
	while (1) {
		if (f < (struct cbfile *)(0xffffffff - ntohl(header->romsize)))
			return NULL;
		if (f->magic == 0)
			return NULL;
		if (f->magic == LARCHIVE_MAGIC)
			return f;
		f = (struct cbfile *)((u8 *)f + ntohl(header->align));
	}
}

static struct cbfile *firstfile(void)
{
	return getfile((void *)(0 - ntohl(header->romsize) +
				ntohl(header->offset)));
}

static struct cbfile *nextfile(struct cbfile *f)
{
	f = (struct cbfile *)((u8 *)f + ALIGN_UP(ntohl(f->len) + ntohl(f->offset),
			      ntohl(header->align)));
	return getfile(f);
}

static struct cbfile *findfile(const char *filename)
{
	struct cbfile *f;
	for (f = firstfile(); f; f = nextfile(f)) {
		if (strcmp(filename, f->filename) == 0)
			return f;
	}
	return NULL;
}

static int cbfs_module_init(void)
{
	struct cbfile *f;
	int index = 0;

	header = *(void **)HEADER_ADDR;
	if (header->magic != ntohl(HEADER_MAGIC)) {
		header = NULL;
		return 0;
	}

	for (f = firstfile(); f; f = nextfile(f))
		filecount++;

	filenames = malloc(filecount * sizeof(char *));
	if (filenames == NULL)
		return 0;

	for (f = firstfile(); f; f = nextfile(f))
		filenames[index++] = strdup((const char *)f->filename);

	return 0;
}

static int cbfs_module_redraw(WINDOW * win)
{
	struct cbfile *f;
	int i, row, frow;

	print_module_title(win, "CBFS Listing");

	if (!header) {
		mvwprintw(win, 11, 61 / 2, "Bad or missing CBFS header");
		return 0;
	}

	/* Draw a line down the middle. */
	for (i = 2; i < 21; i++)
		mvwaddch(win, i, 30, ACS_VLINE);

	/* Draw the names down the left side. */
	for (frow = 0; frow < FILES_VISIBLE; frow++) {
		row = 2 + frow;
		i = start_row + frow;
		if (i >= filecount)
			break;
		if (i == selected)
			wattrset(win, COLOR_PAIR(3) | A_BOLD);
		else
			wattrset(win, COLOR_PAIR(2));

		if (strlen(filenames[i]) == 0) {
			if (findfile(filenames[i])->type == COMPONENT_NULL)
				mvwprintw(win, row, 1, "<free space>");
			else
				mvwprintw(win, row, 1, "<unnamed>");
		} else {
			mvwprintw(win, row, 1, "%.25s", filenames[i]);
		}
		/* show scroll arrows */
		if (frow == 0 && start_row > 0) {
			wattrset(win, COLOR_PAIR(2));
			mvwaddch(win, row, 28, ACS_UARROW);
		}
		if (frow == FILES_VISIBLE - 1 && i != filecount - 1) {
			wattrset(win, COLOR_PAIR(2));
			mvwaddch(win, row, 28, ACS_DARROW);
		}
	}

	f = findfile(filenames[selected]);
	if (!f) {
		mvwprintw(win, 11, 32, "ERROR: CBFS component not found");
		return 0;
	}

	wattrset(win, COLOR_PAIR(2));

	/* Draw the file information */
	row = 2;
	/* mvwprintw(win, row++, 32, "Offset: 0x%x", f->offset); *//* FIXME */
	mvwprintw(win, row, 32, "Type: ");
	switch (ntohl(f->type)) {
	case COMPONENT_BOOTBLOCK:
		mvwprintw(win, row++, 38, "bootblock");
		break;
	case COMPONENT_CBFSHEADER:
		mvwprintw(win, row++, 38, "CBFS header");
		break;
	case COMPONENT_STAGE:
		mvwprintw(win, row++, 38, "stage");
		break;
	case COMPONENT_SELF:
		mvwprintw(win, row++, 38, "simple ELF");
		break;
	case COMPONENT_FIT:
		mvwprintw(win, row++, 38, "FIT");
		break;
	case COMPONENT_OPTIONROM:
		mvwprintw(win, row++, 38, "optionrom");
		break;
	case COMPONENT_RAW:
		mvwprintw(win, row++, 38, "raw");
		break;
	case COMPONENT_MICROCODE:
		mvwprintw(win, row++, 38, "microcode");
		break;
	case COMPONENT_CMOS_LAYOUT:
		mvwprintw(win, row++, 38, "cmos layout");
		break;
	case COMPONENT_NULL:
		mvwprintw(win, row++, 38, "free");
		break;
	case COMPONENT_DELETED:
		mvwprintw(win, row++, 38, "deleted");
		break;
	default:
		mvwprintw(win, row++, 38, "Unknown (0x%x)", ntohl(f->type));
		break;
	}
	mvwprintw(win, row++, 32, "Size: %d", ntohl(f->len));
	mvwprintw(win, row++, 32, "Checksum: 0x%x", ntohl(f->checksum));

	return 0;
}

static int cbfs_module_handle(int key)
{
	int ret = 0;

	if (filecount == 0)
		return 0;

	switch (key) {
	case KEY_DOWN:
		if (selected + 1 < filecount) {
			selected++;
			if (selected >= start_row + FILES_VISIBLE - 1)
				start_row = selected - (FILES_VISIBLE - 1);
			ret = 1;
		}
		break;
	case KEY_UP:
		if (selected > 0) {
			selected--;
			if (selected < start_row)
				start_row = selected;
			ret = 1;
		}
		break;
	}

	return ret;
}

struct coreinfo_module cbfs_module = {
	.name = "CBFS",
	.init = cbfs_module_init,
	.redraw = cbfs_module_redraw,
	.handle = cbfs_module_handle
};

#else

struct coreinfo_module cbfs_module = {
};

#endif
