#!/bin/bash

_cobbler_completions()
{
    local cur prev cobbler_type
    declare -A opts

    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"
    COMPREPLY=()
    ITEMS="distro profile system mgmtclass package file repo image"
    ACTIONS="aclsetup buildiso import list replicate report reposync sync version signature hardlink validate-autoinstalls mkloaders"
    ACTION="add copy edit find list remove rename report"
    opts=(
        [distro]="--ctime --depth --mtime --source-repos --tree-build-time --uid --arch --autoinstall-meta --boot-files --boot-loaders --breed --comment --fetchable-files --initrd --kernel --kernel-options --kernel-options-post --mgmt-classes --name --os-version --owners --redhat-management-key --template-files --in-place --help"
        [profile]="--ctime --depth --mtime --uid --autoinstall --autoinstall-meta --boot-files --comment --dhcp-tag --distro --enable-ipxe --enable-menu --fetchable-files --kernel-options --kernel-options-post --mgmt-classes --mgmt-parameters --name --name-servers --name-servers-search --next-server --owners --parent --proxy --redhat-management-key --repos --server --template-files --virt-auto-boot --virt-bridge --virt-cpus --virt-disk-driver --virt-file-size --virt-path --virt-ram --virt-type --in-place --help"
        [system]="--ctime --depth --ipv6-autoconfiguration --mtime --repos-enabled --uid --autoinstall --autoinstall-meta --boot-files --boot-loaders --comment --enable-ipxe --fetchable-files --gateway --hostname --image --ipv6-default-device --kernel-options --kernel-options-post --mgmt-classes --mgmt-parameters --name --name-servers --name-servers-search --netboot-enabled --next-server --owners --power-address --power-id --power-pass --power-type --power-user --power-options --power-identity-file --profile --proxy --redhat-management-key --server --status --template-files --virt-auto-boot --virt-cpus --virt-disk-driver --virt-file-size --virt-path --virt-pxe-boot --virt-ram --virt-type --serial-device --serial-baud-rate --bonding-opts --bridge-opts --cnames --interface, --connected-mode --interface) --dhcp-tag --dns-name --if-gateway --interface) --interface-master --interface-type --ip-address --ipv6-address --ipv6-default-gateway --ipv6-mtu --ipv6-prefix --ipv6-secondaries --interface) --ipv6-static-routes --mac-address --management --mtu --netmask --static --interface) --static-routes --virt-bridge --interface --delete-interface --rename-interface --in-place --help"
        [repo]="--ctime --depth --mtime --parent --uid --apt-components --apt-dists --arch --breed --comment --createrepo-flags --environment --keep-updated --mirror --mirror-locally --name --owners --priority --proxy --rpm-list --yumopts --in-place --help"
        [image]="--ctime --depth --mtime --parent --uid --arch --autoinstall --breed --comment --file --image-type --name --network-count --os-version --owners --virt-auto-boot --virt-bridge --virt-cpus --virt-disk-driver --virt-file-size --virt-path --virt-ram --virt-type --in-place --help"
        [mgmtclass]="--ctime --depth --is-definition --mtime --uid --class-name --comment --files --name --owners --packages --params --in-place --help"
        [package]="--ctime --depth --mtime --uid --action --comment --installer --name --owners --version --in-place --help"
        [file]="--ctime --depth --mtime --uid --action --comment --group --is-dir --mode --name --owner --owners --path --template --in-place --help"
        [import]="--arch --breed --os-version --path --name --available-as --autoinstall --rsync-flags --help"
        [buildiso]="--iso --profiles --systems --tempdir --distro --standalone --source --exclude-dns --mkisofs-opts --help"
        [replicate]="--master --distros --profiles --systems --repos-pattern --images --prune --omit-data --help"
        [sync]="--dns --dhcp --systems --help"
        [reposync]="--only --tries --no-fail --help"
    )

    if [ "$COMP_CWORD" -eq "1" ]; then
        COMPREPLY=($(compgen -W "${ITEMS} ${ACTIONS}" -- ${cur}))
        return 0
    else
        cobbler_type="${COMP_WORDS[1]}"
    fi

    # Check some special flags before doing normal completion.
    case "${prev}" in
        --name)
            if [ -d "/var/lib/cobbler/collections/${cobbler_type}s" ]; then
                conf="$(ls /var/lib/cobbler/collections/${cobbler_type}s)"
                : "${conf//.json/}"
                COMPREPLY=( $(compgen -W "$(echo $_)" -- ${cur}) )
            fi
            return 0
            ;;
        --distro)
            conf="$(ls /var/lib/cobbler/collections/distros)"
            : "${conf//.json/}"
            COMPREPLY=( $(compgen -W "$(echo $_)" -- ${cur}) )
            return 0
            ;;
        --image)
            conf="$(ls /var/lib/cobbler/collections/images)"
            : "${conf//.json/}"
            COMPREPLY=( $(compgen -W "$(echo $_)" -- ${cur}) )
            return 0
            ;;
        --profile)
            conf="$(ls /var/lib/cobbler/collections/profiles)"
            : "${conf//.json/}"
            COMPREPLY=( $(compgen -W "$(echo $_)" -- ${cur}) )
            return 0
            ;;
        --repos)
            conf="$(ls /var/lib/cobbler/collections/repos)"
            : "${conf//.json/}"
            COMPREPLY=( $(compgen -W "$(echo $_)" -- ${cur}) )
            return 0
            ;;
        --path|--tempdir|--kernel|--initrd)
            # https://superuser.com/a/564776
            local IFS=$'\n'
            local LASTCHAR=' '

            COMPREPLY=($(compgen -o plusdirs -f -- "${COMP_WORDS[COMP_CWORD]}"))

            if [ ${#COMPREPLY[@]} = 1 ]; then
                [ -d "$COMPREPLY" ] && LASTCHAR=/
                COMPREPLY=$(printf %q%s "$COMPREPLY" "$LASTCHAR")
            else
                for ((i=0; i < ${#COMPREPLY[@]}; i++)); do
                    [ -d "${COMPREPLY[$i]}" ] && COMPREPLY[$i]=${COMPREPLY[$i]}/
                done
            fi

            return 0
            ;;
    esac

    case "$cobbler_type" in
        distro|repo|image|mgmtclass|package|file)
            if [ "$COMP_CWORD" -eq "2" ]; then
                COMPREPLY=($(compgen -W "${ACTION}" -- ${cur}))
                return 0
            else
                item_subaction="${COMP_WORDS[2]}"
                case "$item_subaction" in
                    add|edit)
                        COMPREPLY=($(compgen -W "${opts[${cobbler_type}]}" -- ${cur}))
                        return 0
                        ;;
                    list)
                        return 0
                        ;;
                    copy|rename)
                        COMPREPLY=($(compgen -W "${opts[${cobbler_type}]} --newname" -- ${cur}))
                        return 0
                        ;;
                    remove|report)
                        COMPREPLY=($(compgen -W "--name" -- ${cur}))
                        return 0
                        ;;
                    *)
                        return 0
                        ;;
                esac
            fi
            ;;
        profile|system)
            if [ "$COMP_CWORD" -eq "2" ]; then
                COMPREPLY=($(compgen -W "${ACTION} get-autoinstall" -- ${cur}))
                return 0
            else
                item_subaction="${COMP_WORDS[2]}"
                case "$item_subaction" in
                    add|edit)
                        COMPREPLY=($(compgen -W "${opts[${cobbler_type}]}" -- ${cur}))
                        return 0
                        ;;
                    list)
                        return 0
                        ;;
                    copy|rename)
                        COMPREPLY=($(compgen -W "${opts[${cobbler_type}]} --newname" -- ${cur}))
                        return 0
                        ;;
                    get-autoinstall|remove|report)
                        COMPREPLY=($(compgen -W "--name" -- ${cur}))
                        return 0
                        ;;
                    *)
                        return 0
                        ;;
                esac
            fi
            ;;
        import|buildiso|replicate|sync|reposync)
            # FIXME: sync - --systems and --dhcp/--dns are mutually exclusive
            # FIXME: reposync - --no-fail is the only real flag, the other options are key-value pairs
            if [ "$COMP_CWORD" -ge "2" ]; then
                COMPREPLY=($(compgen -W "${opts[${cobbler_type}]}" -- ${cur}))
            fi
            return 0
            ;;
        signature)
            SIGNATURE_OPTIONS="reload report update"
            SIGNATURE_RELOAD_FLAGS="--filename"
            SIGNATURE_REPORT_FLAGS="--name"
            
            if [ "$COMP_CWORD" -eq "2" ]; then
                COMPREPLY=($(compgen -W "${SIGNATURE_OPTIONS}" -- ${cur}))
                return 0
            elif [ "$COMP_CWORD" -eq "3" ]; then
                if [ "$prev" == "reload" ]; then
                    COMPREPLY=($(compgen -W "${SIGNATURE_RELOAD_FLAGS}" -- ${cur}))
                elif [ "$prev" == "report" ]; then
                    COMPREPLY=($(compgen -W "${SIGNATURE_REPORT_FLAGS}" -- ${cur}))
                fi
            fi
            return 0
            ;;
        *)
            return 0
            ;;
    esac
}

complete -F _cobbler_completions cobbler
