#compdef shh

autoload -U is-at-least

_shh() {
    typeset -A opt_args
    typeset -a _arguments_options
    local ret=1

    if is-at-least 5.2; then
        _arguments_options=(-s -S -C)
    else
        _arguments_options=(-s -C)
    fi

    local context curcontext="$curcontext" state line
    _arguments "${_arguments_options[@]}" : \
'-h[Print help]' \
'--help[Print help]' \
'-V[Print version]' \
'--version[Print version]' \
":: :_shh_commands" \
"*::: :->shh" \
&& ret=0
    case $state in
    (shh)
        words=($line[1] "${words[@]}")
        (( CURRENT += 1 ))
        curcontext="${curcontext%:*:*}:shh-command-$line[1]:"
        case $line[1] in
            (run)
_arguments "${_arguments_options[@]}" : \
'-i+[Systemd instance of the service ("system" or "user" for per-user instances of the service manager)]:INSTANCE:(system user)' \
'--instance=[Systemd instance of the service ("system" or "user" for per-user instances of the service manager)]:INSTANCE:(system user)' \
'-m+[How hard we should harden]:MODE:((generic\:"Try to generate hardening options that are more likely be portable across different systems for this service. WARNING\: This is a best effort attempt, and NOT a guarantee. The only way to ensure the options will work is to run profiling on the same exact system"
standard\:"Only generate hardening options if they have a negligible risk of breaking things"
aggressive\:"Will harden further and prevent circumventing restrictions of some options, but may increase the risk of breaking services. It is highly recommended to manually review the generated options"))' \
'--mode=[How hard we should harden]:MODE:((generic\:"Try to generate hardening options that are more likely be portable across different systems for this service. WARNING\: This is a best effort attempt, and NOT a guarantee. The only way to ensure the options will work is to run profiling on the same exact system"
standard\:"Only generate hardening options if they have a negligible risk of breaking things"
aggressive\:"Will harden further and prevent circumventing restrictions of some options, but may increase the risk of breaking services. It is highly recommended to manually review the generated options"))' \
'--merge-paths-threshold=[When using whitelist-based filesystem hardening, if path whitelist is longer than this value, try to merge paths with the same parent]:MERGE_PATHS_THRESHOLD:_default' \
'*--systemd-options=[Disable all systemd options except these (case sensitive). Other options may be generated when mutating these options to make them compatible with profiling data. For testing only]:SYSTEMD_OPTIONS:_default' \
'-p+[Generate profile data file to be merged with others instead of generating systemd options directly]:PROFILE_DATA_PATH:_files' \
'--profile-data-path=[Generate profile data file to be merged with others instead of generating systemd options directly]:PROFILE_DATA_PATH:_files' \
'-l+[Log strace output to this file. Only use for debugging\: this will slow down processing, and may generate a huge file]:STRACE_LOG_PATH:_files' \
'--strace-log-path=[Log strace output to this file. Only use for debugging\: this will slow down processing, and may generate a huge file]:STRACE_LOG_PATH:_files' \
'-c[EXPERIMENTAL Assume the systemd .service unit has been generated from a .container template]' \
'--container[EXPERIMENTAL Assume the systemd .service unit has been generated from a .container template]' \
'-f[Enable advanced network firewalling. Only use this if you know that the network addresses and ports of local system and remote peers will not change]' \
'--network-firewalling[Enable advanced network firewalling. Only use this if you know that the network addresses and ports of local system and remote peers will not change]' \
'-w[Enable whitelist-based filesystem hardening. Only use this if you know that the paths accessed by the service will not change]' \
'--filesystem-whitelisting[Enable whitelist-based filesystem hardening. Only use this if you know that the paths accessed by the service will not change]' \
'-h[Print help (see more with '\''--help'\'')]' \
'--help[Print help (see more with '\''--help'\'')]' \
'*::command -- The command line to run:_default' \
&& ret=0
;;
(merge-profile-data)
_arguments "${_arguments_options[@]}" : \
'-i+[Systemd instance of the service ("system" or "user" for per-user instances of the service manager)]:INSTANCE:(system user)' \
'--instance=[Systemd instance of the service ("system" or "user" for per-user instances of the service manager)]:INSTANCE:(system user)' \
'-m+[How hard we should harden]:MODE:((generic\:"Try to generate hardening options that are more likely be portable across different systems for this service. WARNING\: This is a best effort attempt, and NOT a guarantee. The only way to ensure the options will work is to run profiling on the same exact system"
standard\:"Only generate hardening options if they have a negligible risk of breaking things"
aggressive\:"Will harden further and prevent circumventing restrictions of some options, but may increase the risk of breaking services. It is highly recommended to manually review the generated options"))' \
'--mode=[How hard we should harden]:MODE:((generic\:"Try to generate hardening options that are more likely be portable across different systems for this service. WARNING\: This is a best effort attempt, and NOT a guarantee. The only way to ensure the options will work is to run profiling on the same exact system"
standard\:"Only generate hardening options if they have a negligible risk of breaking things"
aggressive\:"Will harden further and prevent circumventing restrictions of some options, but may increase the risk of breaking services. It is highly recommended to manually review the generated options"))' \
'--merge-paths-threshold=[When using whitelist-based filesystem hardening, if path whitelist is longer than this value, try to merge paths with the same parent]:MERGE_PATHS_THRESHOLD:_default' \
'*--systemd-options=[Disable all systemd options except these (case sensitive). Other options may be generated when mutating these options to make them compatible with profiling data. For testing only]:SYSTEMD_OPTIONS:_default' \
'-c[EXPERIMENTAL Assume the systemd .service unit has been generated from a .container template]' \
'--container[EXPERIMENTAL Assume the systemd .service unit has been generated from a .container template]' \
'-f[Enable advanced network firewalling. Only use this if you know that the network addresses and ports of local system and remote peers will not change]' \
'--network-firewalling[Enable advanced network firewalling. Only use this if you know that the network addresses and ports of local system and remote peers will not change]' \
'-w[Enable whitelist-based filesystem hardening. Only use this if you know that the paths accessed by the service will not change]' \
'--filesystem-whitelisting[Enable whitelist-based filesystem hardening. Only use this if you know that the paths accessed by the service will not change]' \
'-h[Print help (see more with '\''--help'\'')]' \
'--help[Print help (see more with '\''--help'\'')]' \
'*::paths -- Profile data paths:_files' \
&& ret=0
;;
(service)
_arguments "${_arguments_options[@]}" : \
'-h[Print help]' \
'--help[Print help]' \
":: :_shh__service_commands" \
"*::: :->service" \
&& ret=0

    case $state in
    (service)
        words=($line[1] "${words[@]}")
        (( CURRENT += 1 ))
        curcontext="${curcontext%:*:*}:shh-service-command-$line[1]:"
        case $line[1] in
            (start-profile)
_arguments "${_arguments_options[@]}" : \
'-i+[Systemd instance of the service ("system" or "user" for per-user instances of the service manager)]:INSTANCE:(system user)' \
'--instance=[Systemd instance of the service ("system" or "user" for per-user instances of the service manager)]:INSTANCE:(system user)' \
'-m+[How hard we should harden]:MODE:((generic\:"Try to generate hardening options that are more likely be portable across different systems for this service. WARNING\: This is a best effort attempt, and NOT a guarantee. The only way to ensure the options will work is to run profiling on the same exact system"
standard\:"Only generate hardening options if they have a negligible risk of breaking things"
aggressive\:"Will harden further and prevent circumventing restrictions of some options, but may increase the risk of breaking services. It is highly recommended to manually review the generated options"))' \
'--mode=[How hard we should harden]:MODE:((generic\:"Try to generate hardening options that are more likely be portable across different systems for this service. WARNING\: This is a best effort attempt, and NOT a guarantee. The only way to ensure the options will work is to run profiling on the same exact system"
standard\:"Only generate hardening options if they have a negligible risk of breaking things"
aggressive\:"Will harden further and prevent circumventing restrictions of some options, but may increase the risk of breaking services. It is highly recommended to manually review the generated options"))' \
'--merge-paths-threshold=[When using whitelist-based filesystem hardening, if path whitelist is longer than this value, try to merge paths with the same parent]:MERGE_PATHS_THRESHOLD:_default' \
'*--systemd-options=[Disable all systemd options except these (case sensitive). Other options may be generated when mutating these options to make them compatible with profiling data. For testing only]:SYSTEMD_OPTIONS:_default' \
'-f[Enable advanced network firewalling. Only use this if you know that the network addresses and ports of local system and remote peers will not change]' \
'--network-firewalling[Enable advanced network firewalling. Only use this if you know that the network addresses and ports of local system and remote peers will not change]' \
'-w[Enable whitelist-based filesystem hardening. Only use this if you know that the paths accessed by the service will not change]' \
'--filesystem-whitelisting[Enable whitelist-based filesystem hardening. Only use this if you know that the paths accessed by the service will not change]' \
'-n[Disable immediate service restart]' \
'--no-restart[Disable immediate service restart]' \
'-r[Disable previous hardening fragment, if it exists]' \
'--refresh[Disable previous hardening fragment, if it exists]' \
'-h[Print help (see more with '\''--help'\'')]' \
'--help[Print help (see more with '\''--help'\'')]' \
':name -- Service unit name:_default' \
&& ret=0
;;
(finish-profile)
_arguments "${_arguments_options[@]}" : \
'-i+[Systemd instance of the service ("system" or "user" for per-user instances of the service manager)]:INSTANCE:(system user)' \
'--instance=[Systemd instance of the service ("system" or "user" for per-user instances of the service manager)]:INSTANCE:(system user)' \
'-a[Automatically apply hardening config]' \
'--apply[Automatically apply hardening config]' \
'-e[Edit generated options before applying them]' \
'--edit[Edit generated options before applying them]' \
'-n[Disable immediate service restart]' \
'--no-restart[Disable immediate service restart]' \
'-h[Print help]' \
'--help[Print help]' \
':name -- Service unit name:_default' \
&& ret=0
;;
(reset)
_arguments "${_arguments_options[@]}" : \
'-i+[Systemd instance of the service ("system" or "user" for per-user instances of the service manager)]:INSTANCE:(system user)' \
'--instance=[Systemd instance of the service ("system" or "user" for per-user instances of the service manager)]:INSTANCE:(system user)' \
'-h[Print help]' \
'--help[Print help]' \
':name -- Service unit name:_default' \
&& ret=0
;;
(help)
_arguments "${_arguments_options[@]}" : \
":: :_shh__service__help_commands" \
"*::: :->help" \
&& ret=0

    case $state in
    (help)
        words=($line[1] "${words[@]}")
        (( CURRENT += 1 ))
        curcontext="${curcontext%:*:*}:shh-service-help-command-$line[1]:"
        case $line[1] in
            (start-profile)
_arguments "${_arguments_options[@]}" : \
&& ret=0
;;
(finish-profile)
_arguments "${_arguments_options[@]}" : \
&& ret=0
;;
(reset)
_arguments "${_arguments_options[@]}" : \
&& ret=0
;;
(help)
_arguments "${_arguments_options[@]}" : \
&& ret=0
;;
        esac
    ;;
esac
;;
        esac
    ;;
esac
;;
(list-systemd-options)
_arguments "${_arguments_options[@]}" : \
'-h[Print help]' \
'--help[Print help]' \
&& ret=0
;;
(gen-man-pages)
_arguments "${_arguments_options[@]}" : \
'-h[Print help]' \
'--help[Print help]' \
':dir -- Target directory (must exist):_files' \
&& ret=0
;;
(gen-shell-completions)
_arguments "${_arguments_options[@]}" : \
'-s+[Shell to generate for, leave empty for all]:SHELL:(bash elvish fish powershell zsh)' \
'--shell=[Shell to generate for, leave empty for all]:SHELL:(bash elvish fish powershell zsh)' \
'-h[Print help]' \
'--help[Print help]' \
'::dir -- Target directory, leave empty to write to standard output:_files' \
&& ret=0
;;
(help)
_arguments "${_arguments_options[@]}" : \
":: :_shh__help_commands" \
"*::: :->help" \
&& ret=0

    case $state in
    (help)
        words=($line[1] "${words[@]}")
        (( CURRENT += 1 ))
        curcontext="${curcontext%:*:*}:shh-help-command-$line[1]:"
        case $line[1] in
            (run)
_arguments "${_arguments_options[@]}" : \
&& ret=0
;;
(merge-profile-data)
_arguments "${_arguments_options[@]}" : \
&& ret=0
;;
(service)
_arguments "${_arguments_options[@]}" : \
":: :_shh__help__service_commands" \
"*::: :->service" \
&& ret=0

    case $state in
    (service)
        words=($line[1] "${words[@]}")
        (( CURRENT += 1 ))
        curcontext="${curcontext%:*:*}:shh-help-service-command-$line[1]:"
        case $line[1] in
            (start-profile)
_arguments "${_arguments_options[@]}" : \
&& ret=0
;;
(finish-profile)
_arguments "${_arguments_options[@]}" : \
&& ret=0
;;
(reset)
_arguments "${_arguments_options[@]}" : \
&& ret=0
;;
        esac
    ;;
esac
;;
(list-systemd-options)
_arguments "${_arguments_options[@]}" : \
&& ret=0
;;
(gen-man-pages)
_arguments "${_arguments_options[@]}" : \
&& ret=0
;;
(gen-shell-completions)
_arguments "${_arguments_options[@]}" : \
&& ret=0
;;
(help)
_arguments "${_arguments_options[@]}" : \
&& ret=0
;;
        esac
    ;;
esac
;;
        esac
    ;;
esac
}

(( $+functions[_shh_commands] )) ||
_shh_commands() {
    local commands; commands=(
'run:Run a program to profile its behavior' \
'merge-profile-data:Merge profile data from previous runs to generate systemd options' \
'service:Act on a systemd service unit' \
'list-systemd-options:Dump markdown formatted list of supported systemd options' \
'gen-man-pages:Generate man pages' \
'gen-shell-completions:Generate shell completion' \
'help:Print this message or the help of the given subcommand(s)' \
    )
    _describe -t commands 'shh commands' commands "$@"
}
(( $+functions[_shh__gen-man-pages_commands] )) ||
_shh__gen-man-pages_commands() {
    local commands; commands=()
    _describe -t commands 'shh gen-man-pages commands' commands "$@"
}
(( $+functions[_shh__gen-shell-completions_commands] )) ||
_shh__gen-shell-completions_commands() {
    local commands; commands=()
    _describe -t commands 'shh gen-shell-completions commands' commands "$@"
}
(( $+functions[_shh__help_commands] )) ||
_shh__help_commands() {
    local commands; commands=(
'run:Run a program to profile its behavior' \
'merge-profile-data:Merge profile data from previous runs to generate systemd options' \
'service:Act on a systemd service unit' \
'list-systemd-options:Dump markdown formatted list of supported systemd options' \
'gen-man-pages:Generate man pages' \
'gen-shell-completions:Generate shell completion' \
'help:Print this message or the help of the given subcommand(s)' \
    )
    _describe -t commands 'shh help commands' commands "$@"
}
(( $+functions[_shh__help__gen-man-pages_commands] )) ||
_shh__help__gen-man-pages_commands() {
    local commands; commands=()
    _describe -t commands 'shh help gen-man-pages commands' commands "$@"
}
(( $+functions[_shh__help__gen-shell-completions_commands] )) ||
_shh__help__gen-shell-completions_commands() {
    local commands; commands=()
    _describe -t commands 'shh help gen-shell-completions commands' commands "$@"
}
(( $+functions[_shh__help__help_commands] )) ||
_shh__help__help_commands() {
    local commands; commands=()
    _describe -t commands 'shh help help commands' commands "$@"
}
(( $+functions[_shh__help__list-systemd-options_commands] )) ||
_shh__help__list-systemd-options_commands() {
    local commands; commands=()
    _describe -t commands 'shh help list-systemd-options commands' commands "$@"
}
(( $+functions[_shh__help__merge-profile-data_commands] )) ||
_shh__help__merge-profile-data_commands() {
    local commands; commands=()
    _describe -t commands 'shh help merge-profile-data commands' commands "$@"
}
(( $+functions[_shh__help__run_commands] )) ||
_shh__help__run_commands() {
    local commands; commands=()
    _describe -t commands 'shh help run commands' commands "$@"
}
(( $+functions[_shh__help__service_commands] )) ||
_shh__help__service_commands() {
    local commands; commands=(
'start-profile:Add fragment config to service to profile its behavior' \
'finish-profile:Get profiling result and remove fragment config from service' \
'reset:Remove profiling and/or hardening config fragments, and restart service to restore its initial state' \
    )
    _describe -t commands 'shh help service commands' commands "$@"
}
(( $+functions[_shh__help__service__finish-profile_commands] )) ||
_shh__help__service__finish-profile_commands() {
    local commands; commands=()
    _describe -t commands 'shh help service finish-profile commands' commands "$@"
}
(( $+functions[_shh__help__service__reset_commands] )) ||
_shh__help__service__reset_commands() {
    local commands; commands=()
    _describe -t commands 'shh help service reset commands' commands "$@"
}
(( $+functions[_shh__help__service__start-profile_commands] )) ||
_shh__help__service__start-profile_commands() {
    local commands; commands=()
    _describe -t commands 'shh help service start-profile commands' commands "$@"
}
(( $+functions[_shh__list-systemd-options_commands] )) ||
_shh__list-systemd-options_commands() {
    local commands; commands=()
    _describe -t commands 'shh list-systemd-options commands' commands "$@"
}
(( $+functions[_shh__merge-profile-data_commands] )) ||
_shh__merge-profile-data_commands() {
    local commands; commands=()
    _describe -t commands 'shh merge-profile-data commands' commands "$@"
}
(( $+functions[_shh__run_commands] )) ||
_shh__run_commands() {
    local commands; commands=()
    _describe -t commands 'shh run commands' commands "$@"
}
(( $+functions[_shh__service_commands] )) ||
_shh__service_commands() {
    local commands; commands=(
'start-profile:Add fragment config to service to profile its behavior' \
'finish-profile:Get profiling result and remove fragment config from service' \
'reset:Remove profiling and/or hardening config fragments, and restart service to restore its initial state' \
'help:Print this message or the help of the given subcommand(s)' \
    )
    _describe -t commands 'shh service commands' commands "$@"
}
(( $+functions[_shh__service__finish-profile_commands] )) ||
_shh__service__finish-profile_commands() {
    local commands; commands=()
    _describe -t commands 'shh service finish-profile commands' commands "$@"
}
(( $+functions[_shh__service__help_commands] )) ||
_shh__service__help_commands() {
    local commands; commands=(
'start-profile:Add fragment config to service to profile its behavior' \
'finish-profile:Get profiling result and remove fragment config from service' \
'reset:Remove profiling and/or hardening config fragments, and restart service to restore its initial state' \
'help:Print this message or the help of the given subcommand(s)' \
    )
    _describe -t commands 'shh service help commands' commands "$@"
}
(( $+functions[_shh__service__help__finish-profile_commands] )) ||
_shh__service__help__finish-profile_commands() {
    local commands; commands=()
    _describe -t commands 'shh service help finish-profile commands' commands "$@"
}
(( $+functions[_shh__service__help__help_commands] )) ||
_shh__service__help__help_commands() {
    local commands; commands=()
    _describe -t commands 'shh service help help commands' commands "$@"
}
(( $+functions[_shh__service__help__reset_commands] )) ||
_shh__service__help__reset_commands() {
    local commands; commands=()
    _describe -t commands 'shh service help reset commands' commands "$@"
}
(( $+functions[_shh__service__help__start-profile_commands] )) ||
_shh__service__help__start-profile_commands() {
    local commands; commands=()
    _describe -t commands 'shh service help start-profile commands' commands "$@"
}
(( $+functions[_shh__service__reset_commands] )) ||
_shh__service__reset_commands() {
    local commands; commands=()
    _describe -t commands 'shh service reset commands' commands "$@"
}
(( $+functions[_shh__service__start-profile_commands] )) ||
_shh__service__start-profile_commands() {
    local commands; commands=()
    _describe -t commands 'shh service start-profile commands' commands "$@"
}

if [ "$funcstack[1]" = "_shh" ]; then
    _shh "$@"
else
    compdef _shh shh
fi
