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

_detect_kver() {
    if (( MESON_TEST )); then
        './functions' run_mkinitcpio_func kver "$1" 2>/dev/null
    else
        '@INITCPIO_LIBDIR@/functions' run_mkinitcpio_func kver "$1" 2>/dev/null
    fi
}

_lsinitcpio() {
    local cur opts
    opts=(-a --analyze -c --config -h --help -l --list
          -n --nocolor -V --version -v --verbose -x --extract --cpio --early)

    _get_comp_words_by_ref cur

    case $cur in
        -*) mapfile -t COMPREPLY < <(compgen -W "${opts[*]}" -- "$cur") ;;
        *) _filedir ;;
    esac
}

_find_kernel_versions() {
    local -a matches
    local f kver

    for f in /boot/*; do
        # only match regular files which pass validation
        if [[ ! -L $f && -f $f ]] && kver=$(_detect_kver "$f"); then
            matches+=("$f" "$kver")
        fi
    done

    mapfile -t COMPREPLY < <(compgen -W "${matches[*]}" -- "$cur")
}

_files_from_dirs() {
    local files stripsuf d f

    if [[ $1 = -s ]]; then
        stripsuf=$2
        shift 2
    fi

    for d in "$@"; do
        for f in "$d"/*; do
            [[ -f $f ]] && files+=("${f##*/}")
        done
    done

    printf '%s\n' "${files[@]%$stripsuf}"
}

_mkinitcpio() {
    local cur prev opts
    opts=(-A --addhooks -c --config -D --hookdir -d --generatedir -g --generate -H --hookhelp -h --help -k --kernel
          -L --listhooks -M --automods -n --nocolor --nopost -P --allpresets -p --preset -R --remove -r --moduleroot
          -S --skiphooks -s --save -t --builddir -V --version -v --verbose -z --compress
          -U --cmdline --no-cmdline --kernelimage --osrelease --splash --uki --uefistub --ukiconfig --no-ukify)

    _get_comp_words_by_ref cur prev

    case $prev in
        -[cgU] | --cmdline | --config | --generate | --kernelimage | --osrelease | --splash | --uki | --uefistub | --ukiconfig)
            _filedir
            ;;
        -D | --hookdir | -d | --generatedir | -r | --moduleroot | -t | --builddir)
            _filedir -d
            ;;
        -k | --kernel)
            _find_kernel_versions
            ;;
        -p | --preset)
            mapfile -t COMPREPLY < <(compgen -W "$(_files_from_dirs -s .preset "@SYSCONFDIR@/mkinitcpio.d")" -- "$cur")
            ;;
        -[AHS] | --add | --hookhelp | --skiphooks)
            mapfile -t COMPREPLY < <(compgen -W "$(_files_from_dirs "@INITCPIO_LIBDIR@/install")" -- "$cur")
            ;;
        *)
            mapfile -t COMPREPLY < <(compgen -W "${opts[*]}" -- "$cur")
            ;;
    esac
}

complete -F _mkinitcpio mkinitcpio
complete -F _lsinitcpio lsinitcpio

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