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

#include <cbfs.h>
#include <console/console.h>
#include <security/vboot/misc.h>
#include <stddef.h>
#include <string.h>
#include <ux_locales.h>
#include <vb2_api.h>

#define LANG_ID_MAX 100
#define LANG_ID_LEN 3

#define PRERAM_LOCALES_VERSION_BYTE 0x01
#define PRERAM_LOCALES_NAME "preram_locales"

/* We need different delimiters to deal with the case where 'string_name' is the same as
   'localized_string'. */
#define DELIM_STR 0x00
#define DELIM_NAME 0x01

/*
 * Devices which support early vga have the capability to show localized text in
 * Code Page 437 encoding. (see src/drivers/pc80/vga/vga_font_8x16.c)
 *
 * preram_locales located in CBFS is an uncompressed file located in either RO
 * or RW CBFS. It contains the localization information in the following format:
 *
 * [PRERAM_LOCALES_VERSION_BYTE]
 * [string_name_1] [\x00]
 * [language_id_1] [\x00] [localized_string_1] [\x00]
 * [language_id_2] [\x00] [localized_string_2] [\x00] ...
 * [\x01]
 * [string_name_2] [\x00] ...
 *
 * This file contains tools to locate the file and search for localized strings
 * with specific language ID.
 */

/* Cached state for map (locales_get_map) and unmap (ux_locales_unmap). */
struct preram_locales_state {
	void *data;
	size_t size;
	bool initialized;
};

static struct preram_locales_state cached_state;

void ux_locales_unmap(void)
{
	if (cached_state.initialized) {
		if (cached_state.data)
			cbfs_unmap(cached_state.data);
		cached_state.initialized = false;
		cached_state.size = 0;
		cached_state.data = NULL;
	}
}

/* Get the map address of preram_locales. */
static void *locales_get_map(size_t *size_out, bool unmap)
{
	if (cached_state.initialized) {
		*size_out = cached_state.size;
		return cached_state.data;
	}
	cached_state.initialized = true;
	cached_state.data = cbfs_ro_map(PRERAM_LOCALES_NAME,
					&cached_state.size);
	*size_out = cached_state.size;
	return cached_state.data;
}

/* Move to the next string in the data. Strings are separated by delim. */
static size_t move_next(const char *data, size_t offset, size_t size, char delim)
{
	while (offset < size && data[offset] != delim)
		offset++;
	/* If we found delim, move to the start of the next string. */
	if (offset < size)
		offset++;
	return offset;
}

/* Find the next occurrence of the specific string. Strings are separated by delim. */
static size_t search_for(const char *data, size_t offset, size_t size,
			 const char *str, char delim)
{
	while (offset < size) {
		if (!strncmp(data + offset, str, size - offset))
			return offset;
		offset = move_next(data, offset, size, delim);
	}
	return size;
}

/* Find the next occurrence of the string_name, which should always follow a DELIM_NAME. */
static inline size_t search_for_name(const char *data, size_t offset, size_t size,
				     const char *name)
{
	return search_for(data, offset, size, name, DELIM_NAME);
}

/* Find the next occurrence of the integer ID, where ID is less than 100. */
static size_t search_for_id(const char *data, size_t offset, size_t size,
			    int id)
{
	if (id >= LANG_ID_MAX)
		return offset;
	char int_to_str[LANG_ID_LEN] = {};
	snprintf(int_to_str, LANG_ID_LEN, "%d", id);
	return search_for(data, offset, size, int_to_str, DELIM_STR);
}

const char *ux_locales_get_text(const char *name)
{
	const char *data;
	size_t size, offset, name_offset, next_name_offset, next;
	uint32_t lang_id = 0; /* default language English (0) */
	unsigned char version;

	data = locales_get_map(&size, false);
	if (!data || size == 0) {
		printk(BIOS_ERR, "%s: %s not found.\n", __func__,
		       PRERAM_LOCALES_NAME);
		return NULL;
	}

	if (CONFIG(VBOOT)) {
		/* Get the language ID from vboot API. */
		lang_id = vb2api_get_locale_id(vboot_get_context());
		/* Validity check: Language ID should smaller than LANG_ID_MAX. */
		if (lang_id >= LANG_ID_MAX) {
			printk(BIOS_WARNING, "%s: ID %d too big; fallback to 0.\n",
			       __func__, lang_id);
			lang_id = 0;
		}
	}

	printk(BIOS_INFO, "%s: Search for %s with language ID: %u\n",
	       __func__, name, lang_id);

	/* Check if the version byte is the expected version. */
	version = (unsigned char)data[0];
	if (version != PRERAM_LOCALES_VERSION_BYTE) {
		printk(BIOS_ERR, "%s: The version %u is not the expected one %u\n",
		       __func__, version, PRERAM_LOCALES_VERSION_BYTE);
		return NULL;
	}

	/* Search for name. Skip the version byte. */
	offset = search_for_name(data, 1, size, name);
	if (offset >= size) {
		printk(BIOS_ERR, "%s: Name %s not found.\n", __func__, name);
		return NULL;
	}
	name_offset = offset;

	/* Search for language ID. We should not search beyond the range of the current
	   string_name. */
	next_name_offset = move_next(data, offset, size, DELIM_NAME);
	assert(next_name_offset <= size);
	offset = search_for_id(data,  name_offset, next_name_offset, lang_id);
	/* Language ID not supported; fallback to English if the current language is not
	   English (0). */
	if (offset >= next_name_offset) {
		/* Since we only support a limited charset, it is very normal that a language
		   is not supported and we fallback here silently. */
		if (lang_id != 0)
			offset = search_for_id(data, name_offset, next_name_offset, 0);
		if (offset >= next_name_offset) {
			printk(BIOS_ERR, "%s: Neither %d nor 0 found.\n", __func__, lang_id);
			return NULL;
		}
	}

	/* Move to the corresponding localized_string. */
	offset = move_next(data, offset, next_name_offset, DELIM_STR);
	if (offset >= next_name_offset)
		return NULL;

	/* Validity check that the returned string must be NULL terminated. */
	next = move_next(data, offset, next_name_offset, DELIM_STR) - 1;
	if (next >= next_name_offset || data[next] != '\0') {
		printk(BIOS_ERR, "%s: %s is not NULL terminated.\n",
		       __func__, PRERAM_LOCALES_NAME);
		return NULL;
	}

	return data + offset;
}
