# port(1) completion                                       -*- shell-script -*-

_port()
{
        local cur prev words cword
        _init_completion || return

        local mode count portdir cmdfile i port option PSEUDOPORTS

        PSEUDOPORTS=( all current active inactive installed uninstalled
                      outdated obsolete requested unrequested leaves )

        COMPREPLY=()

        count=0
        for i in ${words[@]}; do
            [ $count -eq $cword ] && break
            # Last parameter was a required parameter, now go back to mode selection
            if [ "${words[((count))]}" == "$portdir" -a "$mode" == "portdir" ] \
                    || [ "${words[((count))]}" == "$cmdfile" -a "$mode" == "cmdfile" ]; then
                mode=""
            fi
            if [ -z "$mode" ]; then
                case $i in
                    -D)
                        mode=portdir
                        portdir=${words[((count+1))]}
                        ;;
                    -F)
                        mode=cmdfile
                        cmdfile=${words[((count+1))]}
                        ;;
                    activate|archive|archivefetch|build|bump|cat|cd|checksum|clean|configure|\
                        contents|deactivate|dependents|deps|destroot|diagnose|dir|distcheck|\
                        distfiles|dmg|dpkg|echo|ed|edit|extract|fetch|file|gohome|help|\
                        info|install|installed|lint|list|livecheck|load|location|log|\
                        logfile|mdmg|mirror|mpkg|notes|outdated|patch|pkg|platform|\
                        portpkg|provides|quit|rdependents|rdeps|reclaim|reload|rev-upgrade|\
                        search|select|selfupdate|setrequested|space|submit|sync|test|\
                        unarchive|uninstall|unload|unsetrequested|upgrade|url|usage|\
                        variants|version|work)
                        mode=$i
                        ;;
                esac
            elif [ -z "$port" ]; then
                if [[ $i != -* ]]; then
                    case $mode in
                        contents|uninstall|upgrade)
                            if command port -q installed -- "$i" | awk '{print $1}' | grep -qi '^'$i'$'; then
                                port=$i
                            fi
                            ;;
                        select)
                            port=$i
                            ;;
                        *)
                            if command port -q search --name --exact -- "$i" | grep -qi '^'$i'$'; then
                                port=$i
                            fi
                            ;;
                    esac
                fi
            elif [ -z "$option" ]; then
                if [[ $i != -* ]]; then
                    case $mode in
                        select)
                            option=$i
                            ;;
                    esac
                fi
            fi
            count=$((++count))
        done

        if [ -n "$port" ]; then
            # complete variants
            case $mode in
                contents|uninstall)
                    # installed variants
                    COMPREPLY=( $( command port -q installed -- "$port" \
                        | awk '{print $2}' | tr '\n' ' ' 2>/dev/null ) )
                    COMPREPLY=( $( compgen -W '${COMPREPLY[@]}' -- $cur ) )
                    return 0
                    ;;
                activate)
                    # inactive variants
                    COMPREPLY=( $( command port -q installed -- "$port" | grep -v '(active)' \
                        | awk '{print $2}' | tr '\n' ' ' 2>/dev/null ) )
                    COMPREPLY=( $( compgen -W '${COMPREPLY[@]}' -- $cur ) )
                    return 0
                    ;;
                deactivate)
                    # active variants
                    COMPREPLY=( $( command port -q installed -- "$port" | grep '(active)' \
                        | awk '{print $2}' | tr '\n' ' ' 2>/dev/null ) )
                    COMPREPLY=( $( compgen -W '${COMPREPLY[@]}' -- $cur ) )
                    return 0
                    ;;
                select)
                    if [ -z "$option" ]; then
                        COMPREPLY=( $( command port -q select --list "$port" \
                            | awk '{print $1}' 2>/dev/null ) )
                        COMPREPLY=( $( compgen -W '${COMPREPLY[@]}' -- $cur ) )
                    fi
                    return 0
                    ;;
                *)
                    # all variants
                    COMPREPLY=( $( command port -q info --line --variants -- "$port" | tr '\n,' '  ' ) )
                    COMPREPLY=( $( compgen -P'+' -W '${COMPREPLY[@]}' -- ${cur/+/} ) )
                    return 0
                    ;;
            esac

        fi

        if [ -n "$mode" ]; then
            if [[ $cur == -* ]]; then
                # complete options
                COMPREPLY=( $( command port -q usage -- "$mode" 2>&1 | sed 's/Usage: $mode //' ) )
                COMPREPLY=( $( compgen -W '${COMPREPLY[@]}' -- $cur ) )
                return 0
            else
                # complete port names
                case $mode in
                    contents|installed|outdated|uninstall|upgrade|setrequested|unsetrequested)
                        # installed ports
                        COMPREPLY=( $( command port -q installed -- "$cur*" \
                            | awk '{print $1}' | uniq ) \
                            $( compgen -W '${PSEUDOPORTS[@]}' -- $cur ) \
                        )
                        return 0
                        ;;
                    activate)
                        # inactive ports
                        COMPREPLY=( $( command port -q installed -- "$cur*" | grep -v '(active)' \
                            | awk '{print $1}' | uniq ) \
                            $( compgen -W '${PSEUDOPORTS[@]}' -- $cur ) \
                        )
                        return 0
                        ;;
                    deactivate|load|reload|unload)
                        # active ports
                        COMPREPLY=( $( command port -q installed -- "$cur*" | grep '(active)' \
                            | awk '{print $1}' | uniq ) \
                            $( compgen -W '${PSEUDOPORTS[@]}' -- $cur ) \
                        )
                        return 0
                        ;;
                    provides|cmdfile)
                        _filedir
                        return 0
                        ;;
                    portdir)
                        _filedir -d
                        return 0
                        ;;
                    selfupdate|search|sync|platform|rev-upgrade|reclaim|diagnose)
                        # no port
                        return 0
                        ;;
                    select)
                        COMPREPLY=( $( command port -q select --summary 2>/dev/null | grep -v '^Name|^====' \
                            | grep "^$cur" | awk '{print $1}' ) )
                        COMPREPLY=( $( compgen -W '${COMPREPLY[@]}' -- $cur ) )
                        return 0
                        ;;
                    *)
                        # all ports
                        COMPREPLY=( $( command port -q search --name --glob -- "$cur*" 2>/dev/null | uniq ) \
                            $( compgen -W '${PSEUDOPORTS[@]}' -- $cur ) \
                        )
                        return 0
                        ;;
                esac
            fi
        fi

        COMPREPLY=( $( compgen -W '-b -c -d -f -k -n -o -p -q -R -s -t -u -v -y \
                                activate archive archivefetch build cat cd checksum clean configure \
                                contents deactivate dependents deps destroot diagnose dir distcheck \
                                distfiles dmg dpkg echo ed edit extract fetch file gohome help \
                                info install installed lint list livecheck load location log \
                                logfile mdmg mirror mpkg notes outdated patch pkg platform \
                                portpkg provides quit rdependents rdeps reclaim reload rev-upgrade \
                                search select selfupdate setrequested space submit sync test unarchive uninstall \
                                unload unsetrequested upgrade url usage variants version work' -- $cur ) )
        return 0
} &&
complete -F _port port

# ex: ts=4 sw=4 et filetype=sh
