_gdctl()
{
    local cur prev command connector mode scope option value prefix
    local options word i

    COMPREPLY=()
    cur=${COMP_WORDS[COMP_CWORD]}
    prev=${COMP_WORDS[COMP_CWORD-1]}
    command=${COMP_WORDS[1]}

    connector=
    mode=
    scope=global
    for ((i=2; i<COMP_CWORD; i++)); do
        word=${COMP_WORDS[i]}
        case "$word" in
            -L|--logical-monitor)
                scope=logical-monitor
                connector=
                mode=
                ;;
            -M|--monitor)
                if ((i + 1 < COMP_CWORD)); then
                    connector=${COMP_WORDS[i+1]}
                    scope=monitor
                    ((i++))
                fi
                ;;
            --monitor=*)
                connector=${word#*=}
                scope=monitor
                ;;
            -M?*)
                connector=${word#-M}
                scope=monitor
                ;;
            -m|--mode)
                if ((i + 1 < COMP_CWORD)); then
                    mode=${COMP_WORDS[i+1]}
                    ((i++))
                fi
                ;;
            --mode=*)
                mode=${word#*=}
                ;;
            -m?*)
                mode=${word#-m}
                ;;
        esac
    done

    option=$prev
    value=$cur
    prefix=
    if [[ "$cur" == --*=* ]]; then
        option=${cur%%=*}
        value=${cur#*=}
        prefix=$option=
    elif [[ "$cur" == -?* && "$cur" != --* && ${#cur} -gt 2 ]]; then
        option=${cur:0:2}
        value=${cur:2}
        prefix=$option
    fi

    if options=$(gdctl complete value "$command" "$option" "$connector" "$mode"); then
        COMPREPLY=($(compgen -W "$options" -- "$value"))
        if [[ -n "$prefix" ]]; then
            for ((i=0; i<${#COMPREPLY[@]}; i++)); do
                COMPREPLY[i]=$prefix${COMPREPLY[i]}
            done
        fi
        return
    fi

    options=$(gdctl complete options "$command" "$scope")
    COMPREPLY=($(compgen -W "$options" -- "$cur"))
}

complete -F _gdctl gdctl
