#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#

#
# This class knows how to package up [e]glibc. Its shared since prebuild binary toolchains
# may need packaging and its pointless to duplicate this code.
#
# Caller should set GLIBC_INTERNAL_USE_BINARY_LOCALE to one of:
#  "compile" - Use QEMU to generate the binary locale files
#  "precompiled" - The binary locale files are pregenerated and already present
#  "ondevice" - The device will build the locale files upon first boot through the postinst

GLIBC_INTERNAL_USE_BINARY_LOCALE ?= "ondevice"

GLIBC_SPLIT_LC_PACKAGES ?= "0"

python __anonymous () {
    enabled = d.getVar("ENABLE_BINARY_LOCALE_GENERATION")

    pn = d.getVar("PN")
    if pn.endswith("-initial"):
        enabled = False

    if enabled and int(enabled):
        import re

        target_arch = d.getVar("TARGET_ARCH")
        binary_arches = d.getVar("BINARY_LOCALE_ARCHES") or ""
        use_cross_localedef = d.getVar("LOCALE_GENERATION_WITH_CROSS-LOCALEDEF") or ""

        for regexp in binary_arches.split(" "):
            r = re.compile(regexp)

            if r.match(target_arch):
                depends = d.getVar("DEPENDS")
                if use_cross_localedef == "1" :
                    depends = "%s cross-localedef-native" % depends
                else:
                    depends = "%s qemu-native" % depends
                d.setVar("DEPENDS", depends)
                d.setVar("GLIBC_INTERNAL_USE_BINARY_LOCALE", "compile")
                break
}

# try to fix disable charsets/locales/locale-code compile fail
PACKAGE_NO_GCONV ?= "0"

OVERRIDES:append = ":${TARGET_ARCH}-${TARGET_OS}"

locale_base_postinst_ontarget() {
mkdir ${libdir}/locale
localedef --inputfile=${datadir}/i18n/locales/%s --charmap=%s %s
}

locale_base_postrm() {
#!/bin/sh
localedef --delete-from-archive --inputfile=${datadir}/locales/%s --charmap=%s %s
}

LOCALETREESRC ?= "${PKGD}"

do_prep_locale_tree() {
	treedir=${WORKDIR}/locale-tree
	rm -rf $treedir
	mkdir -p $treedir/${base_bindir} $treedir/${base_libdir} $treedir/${datadir} $treedir/${localedir}
	tar -cf - -C ${LOCALETREESRC}${datadir} -p i18n | tar -xf - -C $treedir/${datadir}
	# unzip to avoid parsing errors
	for i in $treedir/${datadir}/i18n/charmaps/*gz; do 
		gunzip $i
	done
	# The extract pattern "./l*.so*" is carefully selected so that it will
	# match ld*.so and lib*.so*, but not any files in the gconv directory
	# (if it exists). This makes sure we only unpack the files we need.
	# This is important in case usrmerge is set in DISTRO_FEATURES, which
	# means ${base_libdir} == ${libdir}.
	tar -cf - -C ${LOCALETREESRC}${base_libdir} -p . | tar -xf - -C $treedir/${base_libdir} --wildcards './l*.so*'
	if [ -f ${STAGING_LIBDIR_NATIVE}/libgcc_s.* ]; then
		tar -cf - -C ${STAGING_LIBDIR_NATIVE} -p libgcc_s.* | tar -xf - -C $treedir/${base_libdir}
	fi
	install -m 0755 ${LOCALETREESRC}${bindir}/localedef $treedir/${base_bindir}
}

do_collect_bins_from_locale_tree() {
	treedir=${WORKDIR}/locale-tree

	parent=$(dirname ${localedir})
	mkdir -p ${PKGD}/$parent
	tar -cf - -C $treedir/$parent -p $(basename ${localedir}) | tar -xf - -C ${PKGD}$parent

	# Finalize tree by chaning all duplicate files into hard links
	cross-localedef-hardlink -c -v ${WORKDIR}/locale-tree
}

inherit qemu

python package_do_split_gconvs () {
    import re
    if (d.getVar('PACKAGE_NO_GCONV') == '1'):
        bb.note("package requested not splitting gconvs")
        return

    if not d.getVar('PACKAGES'):
        return

    mlprefix = d.getVar("MLPREFIX") or ""

    bpn = d.getVar('BPN')
    libdir = d.getVar('libdir')
    if not libdir:
        bb.error("libdir not defined")
        return
    datadir = d.getVar('datadir')
    if not datadir:
        bb.error("datadir not defined")
        return

    gconv_libdir = oe.path.join(libdir, "gconv")
    charmap_dir = oe.path.join(datadir, "i18n", "charmaps")
    locales_dir = oe.path.join(datadir, "i18n", "locales")
    binary_locales_dir = d.getVar('localedir')

    def calc_gconv_deps(fn, pkg, file_regex, output_pattern, group):
        deps = []
        f = open(fn, "rb")
        c_re = re.compile(r'^copy "(.*)"')
        i_re = re.compile(r'^include "(\w+)".*')
        for l in f.readlines():
            l = l.decode("latin-1")
            m = c_re.match(l) or i_re.match(l)
            if m:
                dp = legitimize_package_name('%s%s-gconv-%s' % (mlprefix, bpn, m.group(1)))
                if not dp in deps:
                    deps.append(dp)
        f.close()
        if deps != []:
            d.setVar('RDEPENDS:%s' % pkg, " ".join(deps))
        if bpn != 'glibc':
            d.setVar('RPROVIDES:%s' % pkg, pkg.replace(bpn, 'glibc'))

    do_split_packages(d, gconv_libdir, file_regex=r'^(.*)\.so$', output_pattern=bpn+'-gconv-%s', \
        description='gconv module for character set %s', hook=calc_gconv_deps, \
        extra_depends=bpn+'-gconv')

    def calc_charmap_deps(fn, pkg, file_regex, output_pattern, group):
        deps = []
        f = open(fn, "rb")
        c_re = re.compile(r'^copy "(.*)"')
        i_re = re.compile(r'^include "(\w+)".*')
        for l in f.readlines():
            l = l.decode("latin-1")
            m = c_re.match(l) or i_re.match(l)
            if m:
                dp = legitimize_package_name('%s%s-charmap-%s' % (mlprefix, bpn, m.group(1)))
                if not dp in deps:
                    deps.append(dp)
        f.close()
        if deps != []:
            d.setVar('RDEPENDS:%s' % pkg, " ".join(deps))
        if bpn != 'glibc':
            d.setVar('RPROVIDES:%s' % pkg, pkg.replace(bpn, 'glibc'))

    do_split_packages(d, charmap_dir, file_regex=r'^(.*)\.gz$', output_pattern=bpn+'-charmap-%s', \
        description='character map for %s encoding', hook=calc_charmap_deps, extra_depends='')

    def calc_locale_deps(fn, pkg, file_regex, output_pattern, group):
        deps = []
        f = open(fn, "rb")
        c_re = re.compile(r'^copy "(.*)"')
        i_re = re.compile(r'^include "(\w+)".*')
        for l in f.readlines():
            l = l.decode("latin-1")
            m = c_re.match(l) or i_re.match(l)
            if m:
                dp = legitimize_package_name(mlprefix+bpn+'-localedata-%s' % m.group(1))
                if not dp in deps:
                    deps.append(dp)
        f.close()
        if deps != []:
            d.setVar('RDEPENDS:%s' % pkg, " ".join(deps))
        if bpn != 'glibc':
            d.setVar('RPROVIDES:%s' % pkg, pkg.replace(bpn, 'glibc'))

    do_split_packages(d, locales_dir, file_regex=r'(.*)', output_pattern=bpn+'-localedata-%s', \
        description='locale definition for %s', hook=calc_locale_deps, extra_depends='')
    d.setVar('PACKAGES', d.getVar('PACKAGES', False) + ' ' + d.getVar('MLPREFIX', False) + bpn + '-gconv')

    use_bin = d.getVar("GLIBC_INTERNAL_USE_BINARY_LOCALE")

    dot_re = re.compile(r"(.*)\.(.*)")

    # Read in supported locales and associated encodings
    supported = {}
    with open(oe.path.join(d.getVar('WORKDIR'), "SUPPORTED")) as f:
        for line in f.readlines():
            try:
                locale, charset = line.rstrip().split()
            except ValueError:
                continue
            supported[locale] = charset

    # GLIBC_GENERATE_LOCALES var specifies which locales to be generated. empty or "all" means all locales
    to_generate = d.getVar('GLIBC_GENERATE_LOCALES')
    if not to_generate or to_generate == 'all':
        to_generate = sorted(supported.keys())
    else:
        to_generate = to_generate.split()
        for locale in to_generate:
            if locale not in supported:
                if '.' in locale:
                    charset = locale.split('.')[1]
                else:
                    charset = 'UTF-8'
                    bb.warn("Unsupported locale '%s', assuming encoding '%s'" % (locale, charset))
                supported[locale] = charset

    def output_locale_source(name, pkgname, locale, encoding):
        d.setVar('RDEPENDS:%s' % pkgname, '%slocaledef %s-localedata-%s %s-charmap-%s' % \
        (mlprefix, mlprefix+bpn, legitimize_package_name(locale), mlprefix+bpn, legitimize_package_name(encoding)))
        d.setVar('pkg_postinst_ontarget:%s' % pkgname, d.getVar('locale_base_postinst_ontarget') \
        % (locale, encoding, locale))
        d.setVar('pkg_postrm:%s' % pkgname, d.getVar('locale_base_postrm') % \
        (locale, encoding, locale))

    def output_locale_binary_rdepends(name, pkgname, locale, encoding):
        dep = legitimize_package_name('%s-binary-localedata-%s' % (bpn, name))
        lcsplit = d.getVar('GLIBC_SPLIT_LC_PACKAGES')
        if lcsplit and int(lcsplit):
            d.appendVar('PACKAGES', ' ' + dep)
            d.setVar('ALLOW_EMPTY:%s' % dep, '1')
        d.setVar('RDEPENDS:%s' % pkgname, mlprefix + dep)

    commands = {}

    def output_locale_binary(name, pkgname, locale, encoding):
        treedir = oe.path.join(d.getVar("WORKDIR"), "locale-tree")
        ldlibdir = oe.path.join(treedir, d.getVar("base_libdir"))
        path = d.getVar("PATH")
        i18npath = oe.path.join(treedir, datadir, "i18n")
        gconvpath = oe.path.join(treedir, "iconvdata")
        outputpath = oe.path.join(treedir, binary_locales_dir)

        use_cross_localedef = d.getVar("LOCALE_GENERATION_WITH_CROSS-LOCALEDEF") or "0"
        if use_cross_localedef == "1":
            target_arch = d.getVar('TARGET_ARCH')
            locale_arch_options = { \
                "arc":     " --uint32-align=4 --little-endian ", \
                "arceb":   " --uint32-align=4 --big-endian ",    \
                "arm":     " --uint32-align=4 --little-endian ", \
                "armeb":   " --uint32-align=4 --big-endian ",    \
                "aarch64": " --uint32-align=4 --little-endian ",    \
                "aarch64_be": " --uint32-align=4 --big-endian ",    \
                "sh4":     " --uint32-align=4 --big-endian ",    \
                "powerpc": " --uint32-align=4 --big-endian ",    \
                "powerpc64": " --uint32-align=4 --big-endian ",  \
                "powerpc64le": " --uint32-align=4 --little-endian ",  \
                "mips":    " --uint32-align=4 --big-endian ",    \
                "mipsisa32r6":    " --uint32-align=4 --big-endian ",    \
                "mips64":  " --uint32-align=4 --big-endian ",    \
                "mipsisa64r6":  " --uint32-align=4 --big-endian ",    \
                "mipsel":  " --uint32-align=4 --little-endian ", \
                "mipsisa32r6el":  " --uint32-align=4 --little-endian ", \
                "mips64el":" --uint32-align=4 --little-endian ", \
                "mipsisa64r6el":" --uint32-align=4 --little-endian ", \
                "riscv64": " --uint32-align=4 --little-endian ", \
                "riscv32": " --uint32-align=4 --little-endian ", \
                "i586":    " --uint32-align=4 --little-endian ", \
                "i686":    " --uint32-align=4 --little-endian ", \
                "x86_64":  " --uint32-align=4 --little-endian ", \
                "loongarch64": " --uint32-align=4 --little-endian "  }

            if target_arch in locale_arch_options:
                localedef_opts = locale_arch_options[target_arch]
            else:
                bb.error("locale_arch_options not found for target_arch=" + target_arch)
                bb.fatal("unknown arch:" + target_arch + " for locale_arch_options")

            localedef_opts += " --force --no-hard-links --no-archive --prefix=%s \
                --inputfile=%s/%s/i18n/locales/%s --charmap=%s %s/%s --no-warnings=ascii" \
                % (treedir, treedir, datadir, locale, encoding, outputpath, name)

            cmd = "PATH=\"%s\" I18NPATH=\"%s\" GCONV_PATH=\"%s\" cross-localedef %s" % \
                (path, i18npath, gconvpath, localedef_opts)
        else: # earlier slower qemu way 
            qemu = qemu_target_binary(d) 
            localedef_opts = "--force --no-hard-links --no-archive --prefix=%s \
                --inputfile=%s/i18n/locales/%s --charmap=%s %s" \
                % (treedir, datadir, locale, encoding, name)

            qemu_options = d.getVar('QEMU_OPTIONS')

            cmd = "PSEUDO_RELOADED=YES PATH=\"%s\" I18NPATH=\"%s\" %s -L %s \
                -E LD_LIBRARY_PATH=%s %s %s${base_bindir}/localedef %s" % \
                (path, i18npath, qemu, treedir, ldlibdir, qemu_options, treedir, localedef_opts)

        commands["%s/%s" % (outputpath, name)] = cmd

        bb.note("generating locale %s (%s)" % (locale, encoding))

    def output_locale(name, locale, encoding):
        pkgname = d.getVar('MLPREFIX', False) + 'locale-base-' + legitimize_package_name(name)
        d.setVar('ALLOW_EMPTY:%s' % pkgname, '1')
        d.setVar('PACKAGES', '%s %s' % (pkgname, d.getVar('PACKAGES')))
        rprovides = ' %svirtual-locale-%s' % (mlprefix, legitimize_package_name(name))
        m = re.match(r"(.*)_(.*)", name)
        if m:
            rprovides += ' %svirtual-locale-%s' % (mlprefix, m.group(1))
        d.setVar('RPROVIDES:%s' % pkgname, rprovides)

        if use_bin == "compile":
            output_locale_binary_rdepends(name, pkgname, locale, encoding)
            output_locale_binary(name, pkgname, locale, encoding)
        elif use_bin == "precompiled":
            output_locale_binary_rdepends(name, pkgname, locale, encoding)
        else:
            output_locale_source(name, pkgname, locale, encoding)

    if use_bin == "compile":
        bb.note("preparing tree for binary locale generation")
        bb.build.exec_func("do_prep_locale_tree", d)

    utf8_is_default = int(d.getVar('LOCALE_UTF8_IS_DEFAULT') or 0)

    encodings = {}
    for locale in to_generate:
        charset = supported[locale]

        m = dot_re.match(locale)
        if m:
            base = m.group(1)
        else:
            base = locale

        # Non-precompiled locales may be renamed so that the default
        # (non-suffixed) encoding is always UTF-8, i.e., instead of en_US and
        # en_US.UTF-8, we have en_US and en_US.ISO-8859-1. This implicitly
        # contradicts SUPPORTED.
        if use_bin == "precompiled" or not utf8_is_default:
            output_locale(locale, base, charset)
        else:
            if charset == 'UTF-8':
                output_locale(base, base, charset)
            else:
                output_locale('%s.%s' % (base, charset), base, charset)

    def metapkg_hook(file, pkg, pattern, format, basename):
        name = basename.split('/', 1)[0]
        metapkg = legitimize_package_name('%s-binary-localedata-%s' % (mlprefix+bpn, name))
        d.appendVar('RDEPENDS:%s' % metapkg, ' ' + pkg)

    if use_bin == "compile":
        makefile = oe.path.join(d.getVar("WORKDIR"), "locale-tree", "Makefile")
        with open(makefile, "w") as m:
            m.write("all: %s\n\n" % " ".join(commands.keys()))
            total = len(commands)
            for i, (maketarget, makerecipe) in enumerate(commands.items()):
                m.write(maketarget + ":\n")
                m.write("\t@echo 'Progress %d/%d'\n" % (i, total))
                m.write("\t" + makerecipe + "\n\n")
        d.setVar("EXTRA_OEMAKE", "-C %s ${PARALLEL_MAKE}" % (os.path.dirname(makefile)))
        d.setVarFlag("oe_runmake", "progress", r"outof:Progress\s(\d+)/(\d+)")
        bb.note("Executing binary locale generation makefile")
        bb.build.exec_func("oe_runmake", d)
        bb.note("collecting binary locales from locale tree")
        bb.build.exec_func("do_collect_bins_from_locale_tree", d)

    if use_bin in ('compile', 'precompiled'):
        lcsplit = d.getVar('GLIBC_SPLIT_LC_PACKAGES')
        if lcsplit and int(lcsplit):
            do_split_packages(d, binary_locales_dir, file_regex=r'^(.*/LC_\w+)', \
                output_pattern=bpn+'-binary-localedata-%s', \
                description='binary locale definition for %s', recursive=True,
                hook=metapkg_hook, extra_depends='', allow_dirs=True, match_path=True)
        else:
            do_split_packages(d, binary_locales_dir, file_regex=r'(.*)', \
                output_pattern=bpn+'-binary-localedata-%s', \
                description='binary locale definition for %s', extra_depends='', allow_dirs=True)
    else:
        bb.note("generation of binary locales disabled. this may break i18n!")

}

# We want to do this indirection so that we can safely 'return'
# from the called function even though we're prepending
python populate_packages:prepend () {
    bb.build.exec_func('package_do_split_gconvs', d)
}
