#!/bin/bash

_voxl_elrs()
{
    local cur prev
    local -a _words
    local _cword
    COMPREPLY=()

    if declare -F _init_completion >/dev/null 2>&1; then
        _init_completion -n '' || return
        _words=("${words[@]}")
        _cword=$cword
    else
        _words=("${COMP_WORDS[@]}")
        _cword=$COMP_CWORD
        cur="${_words[_cword]}"
        prev="${_words[_cword-1]}"
    fi

    # When _init_completion ran, cur/prev already set
    cur="${cur:-${_words[_cword]}}"
    if [[ -z $prev && $_cword -gt 0 ]]; then
        prev="${_words[_cword-1]}"
    fi

    # Disable default filename completion unless we explicitly re-enable it
    compopt +o default +o filenames +o bashdefault 2>/dev/null || true

    local global_opts="-p --port -b --baud -h --help --version"
    local commands="ping get-param set-param enumerate get-params-hash get-rc get-link-stats failsafe pwm-map pwm-map-set pwm-map-tune list-firmware update upload-firmware save-json load-json get-param-json list-presets list-presets-for-sku get-merged-preset load-preset preset-get configure-sku configure arm disarm get-arm-status bind unbind version --version"

    local cmd=""
    local cmd_index=-1
    local i=1
    while (( i < _cword )); do
        local word="${_words[i]}"
        case "$word" in
            -p|--port|-b|--baud)
                (( i++ ))
                (( i < _cword )) && (( i++ ))
                continue
                ;;
        esac
        case "$word" in
            ping|get-param|set-param|enumerate|get-params-hash|get-rc|get-link-stats|failsafe|pwm-map|pwm-map-set|pwm-map-tune|list-firmware|update|upload-firmware|save-json|load-json|get-param-json|list-presets|list-presets-for-sku|get-merged-preset|load-preset|preset-get|configure-sku|configure|arm|disarm|get-arm-status|bind|unbind|version|--version)
                cmd="$word"
                cmd_index=$i
                break
                ;;
        esac
        (( i++ ))
    done

    if [[ -z $cmd ]]; then
        if [[ $cur == -* ]]; then
            COMPREPLY=( $(compgen -W "$global_opts" -- "$cur") )
        else
            COMPREPLY=( $(compgen -W "$commands" -- "$cur") )
        fi
        return 0
    fi

    local arg_pos=$((_cword - cmd_index - 1))

    case "$cmd" in
        ping|enumerate|get-params-hash|get-rc|get-link-stats|failsafe|list-presets|version|--version|arm|disarm|get-arm-status|bind|unbind)
            return 0
            ;;
        get-param|get-param-json)
            if (( arg_pos == 0 )); then
                COMPREPLY=( $(compgen -W "0 1 2 3 4 5 6 7 8 9" -- "$cur") )
            fi
            return 0
            ;;
        set-param)
            if (( arg_pos == 0 )); then
                COMPREPLY=( $(compgen -W "0 1 2 3 4 5 6 7 8 9" -- "$cur") )
            fi
            return 0
            ;;
        pwm-map)
            if (( arg_pos == 0 )); then
                COMPREPLY=( $(compgen -W "0 1 2 3 4 5 6 7" -- "$cur") )
            fi
            return 0
            ;;
        pwm-map-set)
            if [[ $prev == "--mode" ]]; then
                COMPREPLY=( $(compgen -W "off step interp" -- "$cur") )
                return 0
            fi
            if [[ $cur == --* ]]; then
                COMPREPLY=( $(compgen -W "--mode --yes" -- "$cur") )
                return 0
            fi
            case $arg_pos in
                0) COMPREPLY=( $(compgen -W "0 1 2 3 4 5 6 7" -- "$cur") ) ;;
                1) COMPREPLY=( $(compgen -W "1 2 3" -- "$cur") ) ;;
            esac
            return 0
            ;;
        pwm-map-tune)
            if (( arg_pos == 0 )); then
                COMPREPLY=( $(compgen -W "0 1 2 3 4 5 6 7" -- "$cur") )
            fi
            return 0
            ;;
        list-firmware)
            return 0
            ;;
        update|configure)
            if [[ $cur == --* ]]; then
                COMPREPLY=( $(compgen -W "--force" -- "$cur") )
            fi
            return 0
            ;;
        upload-firmware)
            if (( arg_pos == 0 )); then
                compopt -o filenames 2>/dev/null
                COMPREPLY=( $(compgen -f -- "$cur") )
            else
                COMPREPLY=( $(compgen -W "xmodem esp" -- "$cur") )
            fi
            return 0
            ;;
        save-json|load-json)
            compopt -o filenames 2>/dev/null
            COMPREPLY=( $(compgen -f -- "$cur") )
            return 0
            ;;
        list-presets-for-sku|get-merged-preset|load-preset|preset-get|configure-sku)
            return 0
            ;;
    esac
}

complete -F _voxl_elrs voxl-elrs
