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

#include <cbfs.h>
#include <console/console.h>
#include <security/vboot/misc.h>
#include <stddef.h>
#include <stdio.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;
}
