# systemd-analyze(1) completion                      -*- shell-script -*-
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# Copyright © 2010 Ran Benita
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# systemd is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with systemd; If not, see <https://www.gnu.org/licenses/>.

__contains_word () {
    local w word=$1; shift
    for w in "$@"; do
        [[ $w = "$word" ]] && return
    done
}

__get_machines() {
    local a b
    { machinectl list --full --max-addresses=0 --no-legend --no-pager 2>/dev/null; echo ".host"; } | \
	{ while read a b; do echo " $a"; done; } | \
        sort -u
}

__get_units_all() {
    systemctl list-units --no-legend --no-pager --plain --all | \
        { while read -r a b c; do echo " $a"; done }
}

__get_services() {
    systemctl list-units --no-legend --no-pager --plain -t service --all $1 | \
        { while read -r a b c; do [[ $b == "loaded" ]]; echo " $a"; done }
}

__get_syscall_sets() {
    local line
    systemd-analyze syscall-filter --no-pager | while IFS= read -r line; do
        if [[ $line == @* ]]; then
            printf '%s\n' "$line"
        fi
    done
}

_systemd_analyze() {
    local i verb comps mode
    local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword

    local -A OPTS=(
        [STANDALONE]='-h --help --version --system --user --global --order --require --no-pager
                             --man=no --generators=yes --quiet'
        [ARG]='-H --host -M --machine --fuzz --from-pattern --to-pattern --root'
    )

    local -A VERBS=(
        [STANDALONE]='time blame unit-paths exit-status calendar timestamp timespan'
        [CRITICAL_CHAIN]='critical-chain'
        [DOT]='dot'
        [DUMP]='dump'
        [VERIFY]='verify'
        [SECCOMP_FILTER]='syscall-filter'
        [CAT_CONFIG]='cat-config'
        [SECURITY]='security'
        [CONDITION]='condition'
        [INSPECT_ELF]='inspect-elf'
        [PLOT]='plot'
    )

    local CONFIGS='systemd/bootchart.conf systemd/coredump.conf systemd/journald.conf
                       systemd/journal-remote.conf systemd/journal-upload.conf systemd/logind.conf
                       systemd/resolved.conf systemd/networkd.conf systemd/resolved.conf
                       systemd/sleep.conf systemd/system.conf systemd/timedated.conf
                       systemd/timesyncd.conf systemd/user.conf udev/udev.conf'

    _init_completion || return

    for ((i=0; i < COMP_CWORD; i++)); do
        if __contains_word "${COMP_WORDS[i]}" ${VERBS[*]} &&
                ! __contains_word "${COMP_WORDS[i-1]}" ${OPTS[ARG]}; then
            verb=${COMP_WORDS[i]}
            break
        fi
    done

    if __contains_word "$prev" ${OPTS[ARG]}; then
        case $prev in
            --host|-H)
                comps=$(compgen -A hostname)
                ;;
            --machine|-M)
                comps=$( __get_machines )
                ;;
        esac
        COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
        return 0
    fi

    if [[ -z ${verb-}  && $cur = -* ]]; then
        COMPREPLY=( $(compgen -W '${OPTS[*]}' -- "$cur") )
        return 0
    fi

    if [[ -z ${verb-} ]]; then
        comps=${VERBS[*]}

    elif __contains_word "$verb" ${VERBS[STANDALONE]}; then
        if [[ $cur = -* ]]; then
            comps='--help --version --system --user --global --no-pager'
        fi

    elif __contains_word "$verb" ${VERBS[CRITICAL_CHAIN]}; then
        if [[ $cur = -* ]]; then
            comps='--help --version --system --user --fuzz --no-pager'
        else
            comps=$( __get_units_all )
        fi

    elif __contains_word "$verb" ${VERBS[DOT]}; then
        if [[ $cur = -* ]]; then
            comps='--help --version --system --user --global --from-pattern --to-pattern --order --require'
        fi

    elif __contains_word "$verb" ${VERBS[DUMP]}; then
        if [[ $cur = -* ]]; then
            comps='--help --version --system --user --no-pager'
        else
            comps=$( __get_units_all )
        fi

    elif __contains_word "$verb" ${VERBS[SECCOMP_FILTER]}; then
        if [[ $cur = -* ]]; then
            comps='--help --version --no-pager'
        else
            comps=$( __get_syscall_sets )
        fi

    elif __contains_word "$verb" ${VERBS[VERIFY]}; then
        if [[ $cur = -* ]]; then
            comps='--help --version --system --user --global --man=no --generators=yes --root --image --recursive-errors=no --recursive-errors=yes --recursive-errors=one'
        else
            comps=$( compgen -A file -- "$cur" )
            compopt -o filenames
        fi

    elif __contains_word "$verb" ${VERBS[CAT_CONFIG]}; then
        if [[ $cur = -* ]]; then
            comps='--help --version --root --no-pager'
        elif [[ -z $cur ]]; then
            comps="$CONFIGS"
            compopt -o filenames
        else
            comps="$CONFIGS $( compgen -A file -- "$cur" )"
            compopt -o filenames
        fi

    elif __contains_word "$verb" ${VERBS[SECURITY]}; then
        if [[ $cur = -* ]]; then
            comps='--help --version --no-pager --system --user -H --host -M --machine --offline --threshold --security-policy --json=off --json=pretty --json=short --root --image --profile=default --profile=nonetwork --profile=strict --profile=trusted'
        elif ! __contains_word "--offline" ${COMP_WORDS[*]}; then
            if __contains_word "--user" ${COMP_WORDS[*]}; then
                mode=--user
            else
                mode=--system
            fi
            comps=$( __get_services $mode )
        else
            comps="$CONFIGS $( compgen -A file -- "$cur" )"
            compopt -o filenames
        fi

    elif __contains_word "$verb" ${VERBS[CONDITION]}; then
        if [[ $cur = -* ]]; then
            comps='--help --version --system --user --global --no-pager --root --image'
        elif [[ $prev = "-u" ]] || [[ $prev = "--unit" ]]; then
            if __contains_word "--user" ${COMP_WORDS[*]}; then
                mode=--user
            else
                mode=--system
            fi
            comps=$( __get_services $mode )
        fi

    elif __contains_word "$verb" ${VERBS[INSPECT_ELF]}; then
        if [[ $cur = -* ]]; then
            comps='--help --version --json=off --json=pretty --json=short'
        else
            comps=$( compgen -A file -- "$cur" )
            compopt -o filenames
        fi

    elif __contains_word "$verb" ${VERBS[PLOT]}; then
        if [[ $cur = -* ]]; then
            comps='--help --version --system --user --global --no-pager --json=off --json=pretty --json=short --table --no-legend'
        fi
    fi

    COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
    return 0
}

complete -F _systemd_analyze systemd-analyze
