#! /bin/bash
#-*- mode: shell-script;-*-

#
# echo 1 if the command line option is a longopt with '='.
#
function elementExists()
{
    opts_with_equal=(\
        --config-file \
        --controller \
        --color \
        --cluster-id --remote-cluster-id --cluster-name --nodes \
        --properties \
        --vendor --provider-version --os-user \
        --cluster-type --db-admin --db-admin-passwd \
        --account --db-name \
        )

    for i in ${opts_with_equal[@]}; do
        if [ "${opts_with_equal[$i]}" == "$1" ]; then
            echo 1
            break
        fi
    done

    return 0
}

_S9S_MODES="account backup cluster job maintenance \
node process user group script metatype log server \
container tree event alarm sheet replication report"

#
# $*. The options to find.
#
# Returns true if the current command line option list has one option of the
# presented options.
#
function _s9s_has_options()
{
    local option

    for (( i=0; i < COMP_CWORD; i++ )); do
        for option in $*; do
            if [[ ${COMP_WORDS[i]} == "$option" ]]; then
                return 0
            fi
        done
    done
    
    return 1
}

#
# Returns true if the COMMAND part of the command line options is not yet
# entered.
#
function _s9s_no_command()
{
    if ! _s9s_has_options $_S9S_MODES; then
        return 0
    fi

    return 1
}

function _s9s() 
{
    local main_opt
    local cur prev opts

    COMPREPLY=()

    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    if [[ "$prev" == "=" ]]; then
        prev="${COMP_WORDS[COMP_CWORD - 2]}"
    fi
 
    #opts="--help --verbose --version "
    #opts+=" node cluster"

    # 
    # Offering the commands if they are not entered.
    #
    if _s9s_no_command; then
        
        opts+="$_S9S_MODES"
        COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
        return 0
    fi

    for (( i=0; i < COMP_CWORD; i++ )); do
        if [[ ${COMP_WORDS[i]} == "account" ]]; then
            main_opt+="--help "
            main_opt+="--create --list "

            if ! _s9s_has_options $main_opt; then
                opts=$main_opt
            elif [ "$prev" == "--cluster-id" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s cluster --list -l --batch --cluster-format="%I ")
            else
                opts+="--help --verbose --version --config-file= --controller= "
                opts+="--long --print-json --color= --batch "
                opts+="--no-header --only-ascii --wait --log --schedule= "
                opts+="--cluster-id= --cluster-name= --nodes= "
                opts+="--date-format= --cmon-user= --password= "
            fi
            
            COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
            return 0
        elif [[ ${COMP_WORDS[i]} == "backup" ]]; then
            main_opt+="--help "
            main_opt+="--create --delete --list-databases --list-files --list "
            main_opt+="--restore --save-cluster-info --restore-cluster-info "
            main_opt+="--save-controller --restore-controller "

            if ! _s9s_has_options $main_opt; then
                opts=$main_opt
            elif [ "$prev" == "--cluster-id" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s cluster --list -l --batch --cluster-format="%I ")
            else
                opts+="--help --verbose --version --config-file= --controller= "
                opts+="--long --print-json --color= --batch "
                opts+="--no-header --only-ascii --wait --log --schedule= "
                opts+="--cluster-id= --cluster-name= --nodes= "
                opts+="--date-format= --cmon-user= --password= "

                opts+="--backup-id= --backup-format= --backup-datadir "
                opts+="--backup-user= --backup-password= "
                opts+="--backup-directory= --backup-method= --databases= "
                opts+="--full-path= --memory= "
                opts+="--no-compression --on-node --on-controller "
                opts+="--parallellism= --title= --use-pigz "
                opts+="--to-individual-files --pitr-compatible "
            fi
            
            COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
            return 0
        elif [[ ${COMP_WORDS[i]} == "cluster" ]]; then
            main_opt+="--help "
            main_opt+="--add-node --create-account --create --create-database "
            main_opt+="--create-report --delete-account --drop --list "
            main_opt+="--list-databases --ping "
            main_opt+="--remove-node --rolling-restart --setup-audit-logging "
            main_opt+="--import-config --collect-logs "
            main_opt+="--start --stat --stop "
            main_opt+="--enable-recovery --disable-recovery"

            if ! _s9s_has_options $main_opt; then
                opts="$main_opt "
            elif [ "$prev" == "--cluster-id" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s cluster --list -l --batch --cluster-format="%I ")
            elif [ "$prev" == "--cluster-name" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s cluster --list)
            elif [ "$prev" == "--cluster-type" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts+="galera mysqlreplication groupreplication "
                opts+="group_replication ndb ndbcluster postgresql "
            elif [ "$prev" == "--color" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts="never always auto"
            else 
                opts=$(s9s cluster --list)
                opts+="--help --verbose --version " 
                opts+="--config-file= "
                opts+="--controller= "
                opts+="--rpc-tls --cmon-user= --password= "
                opts+="--long --print-json --color= --batch --no-header "
                opts+="--only-ascii "
                opts+="--wait --log --schedule= "
                opts+="--cluster-id= --cluster-name= --nodes= "
                opts+="--properties= --use-internal-repos "
                opts+="--keep-firewall "
                opts+="--vendor= --provider-version= --os-user= "
                opts+="--cluster-type= --db-admin= --db-admin-passwd= "
                opts+="--account= --with-database --db-name= "
                opts+="--output-dir= --donor= "
                opts+="--remote-cluster-id= "

                opts+="--account= "
                opts+="--cloud= "
                opts+="--cluster-format= "
                opts+="--cluster-name= "
                opts+="--cluster-type= "
                opts+="--containers= "
                opts+="--credential-id= "
                opts+="--db-admin-passwd= "
                opts+="--db-admin= "
                opts+="--db-name= "
                opts+="--donor= "
                opts+="--firewalls= "
                opts+="--generate-key "
                opts+="--image= "
                opts+="--image-os-user= "
                opts+="--job-tags= "
                opts+="--nodes= "
                opts+="--opt-group= "
                opts+="--opt-name= "
                opts+="--opt-value= "
                opts+="--os-key-file= "
                opts+="--os-password= "
                opts+="--os-user= "
                opts+="--output-dir= "
                opts+="--provider-version= "
                opts+="--subnet-id= "
                opts+="--template= "
                opts+="--use-internal-repos "
                opts+="--vendor= "
                opts+="--volumes= "
                opts+="--vpc-id= "
                opts+="--with-database "
                opts+="--no-install --with-timescaledb "
                opts+="--config-template= "
            fi 
        elif [[ ${COMP_WORDS[i]} == "job" ]]; then
            main_opt+="--help "
            main_opt+="--delete --fail --list --log --success --wait "

            if ! _s9s_has_options $main_opt; then
                opts=$main_opt
            elif [ "$prev" == "--cmon-user" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s user --list)
            elif [ "$prev" == "--cluster-id" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s cluster --list -l --batch --cluster-format="%I ")
            else
                opts+="--help --verbose --version --config-file= --controller= "
                opts+="--long --print-json --color= --batch "
                opts+="--no-header --only-ascii --wait --log --schedule= "
                opts+="--cluster-id= --cluster-name= --nodes= "
                opts+="--cmon-user= --password= "
           
                opts+="--date-format= "
                opts+="--job-id= --job-tags= --from= --until= --limit= "
                opts+="--offset= "
                opts+="--show-aborted --show-defined --show-failed "
                opts+="--show-finished --show-running --show-scheduled "
            fi
        elif [[ ${COMP_WORDS[i]} == "tree" ]]; then
            main_opt+="--help --access --add-acl --cat --chown --delete "
            main_opt+="--get-acl --list --mkdir --move --remove-acl --rmdir "
            main_opt+="--tree "

            if ! _s9s_has_options $main_opt; then
                opts=$main_opt
            elif [ "$prev" == "--cmon-user" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s user --list)
            else
                opts+="--help --verbose --version --config-file= --controller= "
                opts+="--long --print-json --color= --batch "
                opts+="--no-header --only-ascii --wait --log --schedule= "
                opts+="--cluster-id= --cluster-name= --servers= "
                opts+="--cmon-user= --password= "

                opts+="--acl= "
                opts+=$(s9s tree --list 2>/dev/null | awk '{print $4}')
            fi
        elif [[ ${COMP_WORDS[i]} == "replication" ]]; then
            main_opt+="--help --failover --stage --list --promote"
            main_opt+=" --start --stop "

            if ! _s9s_has_options $main_opt; then
                opts=$main_opt
            elif [ "$prev" == "--cmon-user" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s user --list)
            else
                opts+="--help --verbose --version --config-file= --controller= "
                opts+="--long --print-json --color= --batch "
                opts+="--no-header --only-ascii --wait --log --schedule= "
                opts+="--cluster-id= --cluster-name= "
                opts+="--cmon-user= --password= "

                opts+="--master= --replication-master= --replication-slave= "
                opts+="--slave= "
                opts+=$(s9s tree --list 2>/dev/null | awk '{print $4}')
            fi
        elif [[ ${COMP_WORDS[i]} == "report" ]]; then
            main_opt+="--help --cat --create --delete --list --list-templates "
            if ! _s9s_has_options $main_opt; then
                opts=$main_opt
            elif [ "$prev" == "--type" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s report --list-templates)
            else
                opts+="--help --type= --report-id= "
            fi
        elif [[ ${COMP_WORDS[i]} == "server" ]]; then
            main_opt+="--help "
            main_opt+="--create --list-disks --list-images --list-memory "
            main_opt+="--list-nics --list-partitions --list-processors "
            main_opt+="--list-subnets --list-templates --list-containers "
            main_opt+="--register --unregister --start --stop "
            main_opt+="--tree --unregister --get-acl --set-acl "
            main_opt+="--list-regions "
            
            if ! _s9s_has_options $main_opt; then
                opts=$main_opt
            elif [ "$prev" == "--cmon-user" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s user --list)
            else
                opts+="--help --verbose --version --config-file= --controller= "
                opts+="--long --print-json --color= --batch "
                opts+="--no-header --only-ascii --wait --log --schedule= "
                opts+="--cluster-id= --cluster-name= --servers= "
                opts+="--cmon-user= --password= "
           
                opts+="--date-format= "
                opts+="--job-id= --from= --until= --limit= --offset= "

                opts+="--acl= "
                opts+=$(s9s tree --list --batch --recursive --full-path 2>/dev/null | awk '{print $5}')
            fi
        elif [[ ${COMP_WORDS[i]} == "container" ]]; then
            main_opt+="--help "
            main_opt+="--create --delete --list --start --stat --stop "
            
            if ! _s9s_has_options $main_opt; then
                opts=$main_opt
            elif [ "$prev" == "--cmon-user" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s user --list)
            elif [ "$prev" == "--image" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s server --list-images)
            else
                opts+="--cloud= "
                opts+="--container-format= "
                opts+="--containers= "
                opts+="--credential-id= "
                opts+="--firewalls= "
                opts+="--generate-key "
                opts+="--image= "
                opts+="--image-os-user= "
                opts+="--os-key-file= "
                opts+="--os-password= "
                opts+="--os-user= "
                opts+="--region= "
                opts+="--servers= "
                opts+="--subnet-id= "
                opts+="--template= "
                opts+="--volumes= "
                opts+="--vpc-id= "
            fi
        elif [[ ${COMP_WORDS[i]} == "maintenance" ]]; then
            main_opt="--help "
            main_opt+="--list --create --delete --current --next "

            if ! _s9s_has_options $main_opt; then
                opts=$main_opt
            elif [ "$prev" == "--cluster-id" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s cluster --list -l --batch --cluster-format="%I ")
            elif [ "$prev" == "--cmon-user" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s user --list)
            else
                opts+="--help --verbose --version --config-file= --controller= "
                opts+="--long --print-json --color= --batch "
                opts+="--no-header --only-ascii --wait --log --schedule= "
                opts+="--cluster-id= --cluster-name= --nodes= "

                opts+="--date-format= end= --full-uuid --reason= --start= "
                opts+="--cmon-user= --password= --uuid="
            fi
        elif [[ ${COMP_WORDS[i]} == "event" ]]; then
            main_opt="--help "
            main_opt+="--list "

            if ! _s9s_has_options $main_opt; then
                opts=$main_opt
            elif [ "$prev" == "--cluster-id" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s cluster --list -l --batch --cluster-format="%I ")
            elif [ "$prev" == "--cmon-user" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s user --list)
            else
                opts+="--help --verbose --version --config-file= --controller= "
                opts+="--long --print-json --color= --batch "
                opts+="--no-header --only-ascii "
                opts+="--cluster-id= --cluster-name= --nodes= "

                opts+="--date-format= "
                opts+="--cmon-user= --password= "
                opts+="--with-event-alarm --with-event-cluster "
                opts+="--with-event-debug --with-event-file --with-event-host "
                opts+="--with-event-job --with-event-log "
                opts+="--with-event-maintenance "
            fi
        elif [[ ${COMP_WORDS[i]} == "event" ]]; then
            main_opt="--help "
            main_opt+="--list --delete"

            if ! _s9s_has_options $main_opt; then
                opts=$main_opt
            elif [ "$prev" == "--cluster-id" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s cluster --list -l --batch --cluster-format="%I ")
            elif [ "$prev" == "--cmon-user" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s user --list)
            else
                opts+="--help --verbose --version --config-file= --controller= "
                opts+="--long --print-json --color= --batch "
                opts+="--no-header --only-ascii "
                opts+="--cluster-id= --cluster-name= --nodes= "

                opts+="--date-format= "
                opts+="--cmon-user= --password= "
                opts+="--alarm-id= "
            fi
        elif [[ ${COMP_WORDS[i]} == "log" ]]; then
            main_opt="--help "
            main_opt="--list "

            if ! _s9s_has_options $main_opt; then
                opts=$main_opt
            elif [ "$prev" == "--cluster-id" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s cluster --list -l --batch --cluster-format="%I ")
            elif [ "$prev" == "--cluster-name" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s cluster --list)
            elif [ "$prev" == "--cmon-user" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s user --list)
            else
                opts+="--help --verbose --version --config-file= --controller= "
                opts+="--long --print-json --color= --batch "
                opts+="--no-header --only-ascii --wait "
                opts+="--cluster-id= --cluster-name= "

                opts+="--date-format= "
                opts+="--cmon-user= --password= "
                opts+="--from= --until= "
            fi
        elif [[ ${COMP_WORDS[i]} == "node" ]]; then
            main_opt+="--help "
            main_opt+="--change-config --enable-binary-logging --list-config "
            main_opt+="--list --pull-config "
            main_opt+="--push-config --register --restart --set "
            main_opt+="--set-read-only --set-read-write --start --stat "
            main_opt+="--stop --unregister "

            if ! _s9s_has_options $main_opt; then
                opts=$main_opt
            elif [ "$prev" == "--graph" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts+="cpughz cpuload cputemp cpusys cpuidle cpuiowait cpuuser "
                opts+="diskfree diskreadspeed diskreadwritespeed "
                opts+="diskwritespeed diskutilization "
                opts+="memfree memutil "
                opts+="netreceivedspeed netsentspeed netspeed "
                opts+="netreceiveerrors nettransmiterrors neterrors "
                opts+="sqlcommands sqlstatements sqlconnections "
                opts+="sqlreplicationlag sqlcommits "
                opts+="sqlqueries sqlslowqueries sqlopentables "
                opts+="swapfree "
            elif [ "$prev" == "--cluster-id" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s cluster --list -l --batch --cluster-format="%I ")
            else
                opts+="--help --verbose --version --config-file= --controller= "
                opts+="--long --print-json --color= --batch "
                opts+="--no-header --only-ascii --wait --log --schedule= "
                opts+="--cluster-id= --cluster-name= --nodes= "
                opts+="--cmon-user= --password= "

                opts+="--properties= --begin --end --force --graph= "
                opts+="--node-format= --opt-group= --opt-name= --opt-value= "
                opts+="--output-dir= --properties="
            fi
        elif [[ ${COMP_WORDS[i]} == "script" ]]; then
            main_opt+="--help "
            main_opt+="--tree --execute "

            if ! _s9s_has_options $main_opt; then
                opts=$main_opt
            elif [ "$prev" == "--cmon-user" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s user --list)
            elif [ "$prev" == "--cluster-id" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s cluster --list -l --batch --cluster-format="%I ")
            else
                opts+="--help --verbose --version --config-file= --controller= "
                opts+="--long --print-json --color= --batch "
                opts+="--no-header --only-ascii --wait --log --schedule= "
                opts+="--cluster-id= --cluster-name= --nodes= "
                opts+="--cmon-user= --password= "

                opts+=$(compgen -f -- "${COMP_WORDS[${COMP_CWORD}]}" )
            fi
        elif [[ ${COMP_WORDS[i]} == "process" ]]; then
            main_opt="--list --top --help"

            if ! _s9s_has_options $main_opt; then
                opts=$main_opt
            fi
        elif [[ ${COMP_WORDS[i]} == "user" ]]; then
            main_opt="--help "
            main_opt+="--add-key --add-to-group --change-password --create "
            main_opt+="--disable "
            main_opt+="--enable --list-groups --list-keys --list "
            main_opt+="--remove-from-group "
            main_opt+="--set --set-group --stat --whoami "
            
            if ! _s9s_has_options $main_opt; then
                opts=$main_opt
            elif [ "$prev" == "--cmon-user" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s user --list)
            elif [ "$prev" == "--public-key-file" ]; then
                opts+=$(compgen -f -- "${COMP_WORDS[${COMP_CWORD}]}" )
            else
                opts+="--help --verbose --version " 
                opts+="--config-file= "
                opts+="--controller= "
                opts+="--rpc-tls "
                opts+="--long --print-json --color= --batch --no-header "
                opts+="--group= --create-group --first-name= --last-name= "
                opts+="--title= --email-address= "
                opts+="--account= --with-database --db-name= --user-format= "
                opts+="--cmon-user= --password= "
                opts+="--new-password= --old-password= --public-key-file= "
                opts+="--public-key-name= "
                opts+=$(s9s user --list 2>/dev/null)
            fi
        elif [[ ${COMP_WORDS[i]} == "group" ]]; then
            main_opt="--help "
            main_opt+="--create --list --delete "
            
            if ! _s9s_has_options $main_opt; then
                opts=$main_opt
            elif [ "$prev" == "--cmon-user" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s user --list)
            else
                opts+="--help --verbose --version " 
                opts+="--config-file= "
                opts+="--controller= "
                opts+="--rpc-tls "
                opts+="--long --print-json --color= --batch --no-header "
                opts+="--cmon-user= --password= "
                opts+="--public-key-name= "
                opts+=$(s9s user --list 2>/dev/null)
            fi
        elif [[ ${COMP_WORDS[i]} == "metatype" ]]; then
            main_opt+="--help "
            main_opt+="--list --list-properties "
            
            if ! _s9s_has_options $main_opt; then
                opts=$main_opt
            elif [ "$prev" == "--cmon-user" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s user --list)
            elif [ "$prev" == "--type" ]; then
                prev="${cur%%=*}="
                cur=${cur#*=}
                opts=$(s9s metatype --list)
            else
                opts+="--help --verbose --version --config-file= --controller= "
                opts+="--long --print-json --color= --batch "
                opts+="--no-header --only-ascii --wait --log --schedule= "
                opts+="--cluster-id= --cluster-name= --nodes= "
                opts+="--cmon-user= --password= "
                opts+="--type= "
            fi
        elif [[ ${COMP_WORDS[i]} == "sheet" ]]; then
            main_opt+="--help "
            main_opt+="--list --stat --edit "
            
            if ! _s9s_has_options $main_opt; then
                opts=$main_opt
            else
                opts+="--help --verbose --version --config-file= --controller= "
                opts+="--long --print-json --color= --batch "
                opts+="--cmon-user= --password= "
                opts+="--cluster-id= --cluster-name= "
                # This is bogus, this has cluster id
                opts+=$(s9s sheet --list --cluster-id=1)
            fi
        fi
    done
 
    isEqualOptions=$(elementExists "${cur}")
    if [ "${isEqualOptions:-0}" -eq 1 ]; then
        COMPREPLY=( $(compgen -W "${opts}" -S '=' -- "${cur}") )
    else
        COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
    fi

    return 0
}
complete -o nospace -F _s9s s9s
