#!/bin/sh
#
# Run a wrapped command with at least the requested locales available.
# Requires a dependency on locales | locales-all.
# The requested locales must be of the form foo_FOO.utf8, or special-cased
# in generate(), or listed in /usr/share/i18n/SUPPORTED, or specify the
# locale in the form locale=charset.
#
# Copyright 2016-2021 Simon McVittie
# Copyright 2017-2018 Collabora Ltd.
#
# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.

# Assume a Debian Policy §10.4-compatible shell like dash or bash (with the
# 'local' builtin)
# shellcheck disable=SC2039

set -eu

me="$(basename "$0")"
tempdir=

usage () {
    local status="${1-2}"

    if [ "$status" -ne 0 ]; then
        exec >&2
    fi

    echo "Usage: $me [--generate LOCALE...] [--] COMMAND [ARGS...]"
    exit "$status"
}

getopt_temp=help
getopt_temp="$getopt_temp,generate:"

getopt_temp="$(getopt -o '+' --long "$getopt_temp" -n "$0" -- "$@")"
eval set -- "$getopt_temp"
unset getopt_temp

generate () {
    local locale="$1"
    local charset=""
    local source
    local output

    echo "$me: $locale..." >&2

    case "$locale" in
        (*=*)
            source="${locale%=*}"
            output="$source"
            ;;

        (*.*)
            source="${locale%.*}"
            output="$source.$(
                export LC_ALL=C
                printf '%s' "${locale##*.}" | \
                    tr '[:upper:]' '[:lower:]' | \
                    tr -d -C '[:lower:][:digit:]'
            )"
            ;;

        (*)
            source="${locale}"
            output="${locale}"
    esac

    if [ -e "/usr/lib/locale/$output/LC_MESSAGES/SYS_LC_MESSAGES" ]; then
        printf '\t%s\n' "Found in locales-all" >&2
        return
    fi

    if ! [ -d /usr/share/i18n/charmaps ]; then
        echo "$me: $locale not in locales-all and /usr/share/i18n/charmaps not found" >&2
        return
    fi

    case "$locale" in
        (*=*)
            charset="${locale##*=}"
            ;;

        (*.utf8 | *.UTF-8)
            charset="UTF-8"
            ;;

        (*.*)
            charset="${locale##*.}"
            ;;
    esac

    if [ -z "$charset" ]; then
        echo "$me: $locale charset not known" >&2
        exit 1
    fi

    printf '\t%s\n' "Character set: $charset" >&2
    printf '\t%s\n' "Source file: $source" >&2

    if [ -z "$tempdir" ]; then
        tempdir="$(mktemp -d)"
        trap 'rm -fr "$tempdir"' EXIT
    fi

    printf '\t%s\n' "Output: $tempdir/$output" >&2

    localedef -i "$source" -f "$charset" "$tempdir/$output"
}

while [ "$#" -gt 0 ]; do
    case "$1" in
        (--help)
            usage 2
            # not reached
            ;;

        (--generate)
            generate "$2"
            shift 2
            ;;

        (--)
            shift
            break
            ;;

        (-*)
            echo "$me: Unknown option: $1" >&2
            usage 2
            # not reached
            ;;

        (*)
            break
            ;;
    esac
done

if [ -n "$tempdir" ]; then
    find "$tempdir" >&2
    export LOCPATH="$tempdir"
fi

"$@"

# vim:set sw=4 sts=4 et:
