#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-2.0-only

get_decompressor() {
    case "$1" in
        *.gz)
            cat=zcat
            of=${1%.gz}
            ;;
        *.bz2)
            cat=bzcat
            of=${1%.bz2}
            ;;
        *)
            cat=cat
            of=$1
            ;;
    esac
}

add_keymap_file() {
    local cat cmd rest f of

    while read f; do
        get_decompressor "$f"
        while read -r cmd rest; do
            if [[ $cmd == include ]]; then
                eval set $rest
                add_keymap_file "$1"
            fi
        done < <($cat "$f")
        add_dir "${of%/*}"
        $cat "$f" > "$BUILDROOT/$of"
    done < <(find /usr/share/kbd/keymaps/ -type f -regex ".*/$1\(\.inc\)?\(\.gz\|\.bz2\)?")
}

build() {
    # prevent conflicting variables from affecting vconsole.conf values
    # shellcheck disable=SC2034
    local KEYMAP KEYMAP_TOGGLE FONT FONT_MAP FONT_UNIMAP

    add_binary /usr/lib/systemd/systemd-vconsole-setup
    add_binary loadkeys
    add_binary setfont
    add_file /etc/vconsole.conf
    add_udev_rule 90-vconsole.rules

    # subshell to avoid namespace pollution
    (
        shopt -s extglob nullglob

        add_font_file() {
            local cat file filename fontfile="$1"
            get_decompressor "$fontfile"
            add_dir "${of%/*}"
            "$cat" "$fontfile" > "$BUILDROOT/$of"
            if [[ "$(head -c 23 "$BUILDROOT/$of" | tr -d '\0')" == '# combine partial fonts' ]]; then
                while read filename; do
                    for file in "/usr/share/kbd/consolefonts/partialfonts/$filename"?('.gz'|'.bz2'); do
                        add_font_file "$file"
                    done
                done < <(sed '/^#/d' "$BUILDROOT/$of")
            fi
        }

        [[ -s /etc/vconsole.conf ]] && . /etc/vconsole.conf

        [[ $KEYMAP ]] && add_keymap_file $KEYMAP.map
        [[ $KEYMAP_TOGGLE ]] && add_keymap_file $KEYMAP_TOGGLE.map

        if [[ $FONT ]]; then
            for file in "/usr/share/kbd/consolefonts/$FONT"?('.psfu'|'.psf'|'.cp'|'.fnt')?('.gz'|'.bz2'); do
                add_font_file "$file"
                return
            done
            error "sd-vconsole: requested font not found: '%s'" "$FONT"
            return 1
        fi
    )
}

help() {
    cat <<HELPEOF
This hook adds the keymap(s) and font specified in vconsole.conf to the image and
loads them during early userspace.
HELPEOF
}

# vim: set ft=sh ts=4 sw=4 et:
