/*
 *
 * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#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[1];
} __packed;

struct cbfile {
	u64 magic;
	u32 len;
	u32 type;
	u32 checksum;
	u32 offset;
	char filename[0];
} __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(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
