-- lx-bundle:true

-- This file is part of Lx, created by Liqube <www.liqube.com>
-- Copyright Liqube Audio. All rights reserved.
-- Lx Interim License. See LICENSE for details.

--- Language and localization
-- Based on Language.cpp by Liqube Audio
-- @module language

local data = require("core.i18n.data")
local plural = require("core.i18n.plural")
local i18n = {}

--- Normalize a complete locale key such as "de_at" from "de-AT"
-- @param locale string|nil Locale identifier in any common form
-- @return string Normalized locale key
function i18n.normalize_locale_key(locale)
	if not locale or locale == "" then
		return "en"
	end

	return tostring(locale):lower():gsub("%-", "_")
end

--- Returns a normalized base locale key such as "de" from "de_at" or "pt-BR"
-- Simplifies locale handling for plural resolution and language lookup
-- @param locale string|nil Locale identifier in any common form
-- @return string Base locale code
function i18n.normalize_locale(locale)
	if not locale or locale == "" then
		return "en"
	end
	--- Normalize case and separator, then take the language portion
	local s = i18n.normalize_locale_key(locale)
	return s:match("^[^_]+") or s
end

--- Check whether a language code is right-to-left
-- @param language_code string|nil Language identifier
-- @return boolean True when the language is RTL
function i18n.is_rtl(language_code)
	if not language_code then
		return false
	end
	local locale_key = i18n.normalize_locale_key(language_code)
	local base_key = i18n.normalize_locale(locale_key)

	return data.rtl_codes[locale_key] == true or data.rtl_codes[base_key] == true
end

--- Retrieve language metadata such as display name and plural info
-- Returns nil when the language is unknown
-- @param language_code string|nil Language identifier
-- @return table|nil Language metadata table
function i18n.get_language_data(language_code)
	if not language_code then
		return nil
	end
	local locale_key = i18n.normalize_locale_key(language_code)
	local base_key = i18n.normalize_locale(locale_key)

	return data.languages[locale_key] or data.languages[base_key]
end

--- Compute the plural category for a locale and numeric value
-- This is the resolver used by the i18n renderer for {p:...} blocks
-- Unknown locales fall back to the common one/other rule
-- @param locale string|nil Locale identifier
-- @param n number|nil Numeric value to categorize
-- @return string plural category ("zero"|"one"|"two"|"few"|"many"|"other")
function i18n.get_plural_category(locale, n)
	if type(n) ~= "number" then
		return "other"
	end
	local base = i18n.normalize_locale(locale)
	local language = data.languages[base]

	--- Select resolver, defaulting to the standard one/other rule
	local resolver = (language and language.resolver) or plural.one_other_n1
	return resolver(n)
end

return i18n
