# bash completion for pytest(1)                            -*- shell-script -*-

_pytest()
{
    local cur prev words cword split
    _init_completion -s -n : || return

    case $prev in
        --help | --maxfail | --report | --junit-prefix | --doctest-glob | -!(-*)[hkmorp])
            return
            ;;
        --import-mode)
            COMPREPLY=($(compgen -W "prepend append" -- "$cur"))
            return
            ;;
        --capture)
            COMPREPLY=($(compgen -W "fd sys no tee-sys" -- "$cur"))
            return
            ;;
        --lfnf | --last-failed-no-failures)
            COMPREPLY=($(compgen -W "all none" -- "$cur"))
            return
            ;;
        --tb)
            COMPREPLY=($(compgen -W "auto long short line native no" \
                -- "$cur"))
            return
            ;;
        --show-capture)
            COMPREPLY=($(compgen -W "no stdout stderr log all" -- "$cur"))
            return
            ;;
        --color)
            COMPREPLY=($(compgen -W "yes no auto" -- "$cur"))
            return
            ;;
        --pastebin)
            COMPREPLY=($(compgen -W "failed all" -- "$cur"))
            return
            ;;
        --junit-xml)
            _filedir xml
            return
            ;;
        --result-log | --log-file)
            _filedir log
            return
            ;;
        --ignore)
            _filedir
            return
            ;;
        --confcutdir | --basetemp | --rsyncdir | --rootdir)
            _filedir -d
            return
            ;;
        --doctest-report)
            COMPREPLY=($(compgen -W "none cdiff ndiff udiff only_first_failure" -- "$cur"))
            return
            ;;
        --assert)
            COMPREPLY=($(compgen -W "plain reinterp rewrite" -- "$cur"))
            return
            ;;
        --genscript)
            _filedir py
            return
            ;;
        --pythonwarnings | -!(-*)W)
            _xfunc python _python_warning_actions
            return
            ;;
        --numprocesses | -!(-*)n)
            COMPREPLY=($(compgen -W "{1..$(_ncpus)} auto" -- "$cur"))
            return
            ;;
        --dist)
            local modes=$("$1" --dist=nonexistent-distmode 2>&1 |
                command sed -e 's/[^[:space:][:alnum:]-]\{1,\}//g' \
                    -ne 's/.*choose from //p')
            COMPREPLY=($(compgen -W '$modes' -- "$cur"))
            return
            ;;
    esac

    $split && return

    if [[ $cur == -* ]]; then
        COMPREPLY=($(compgen -W '$(_parse_help "$1")' -- "$cur"))
        [[ ${COMPREPLY-} == *= ]] && compopt -o nospace
        return
    fi

    if [[ $cur == *.py::*:* ]]; then
        local file=${cur/.py:*/.py}
        local class=${cur#*.py::} in_class=false
        local line
        class=${class%%:*}
        while IFS= read -r line; do
            if [[ $line =~ ^class[[:space:]]+${class}[[:space:]:\(] ]]; then
                in_class=true
            elif [[ $line =~ ^class[[:space:]] ]]; then
                in_class=false
            fi
            if $in_class && [[ $line =~ ^[[:space:]]+(async[[:space:]]+)?def[[:space:]]+(test_[A-Za-z0-9_]+) ]]; then
                COMPREPLY+=(${BASH_REMATCH[2]})
            fi
        done 2>/dev/null <"$file"
        ((!${#COMPREPLY[@]})) ||
            COMPREPLY=($(compgen -P "$file::$class::" -W '${COMPREPLY[@]}' \
                -- "${cur##*:?(:)}"))
        __ltrim_colon_completions "$cur"
        return
    elif [[ $cur == *.py:* ]]; then
        local file="${cur/.py:*/.py}" line
        while IFS= read -r line; do
            if [[ $line =~ ^class[[:space:]]+(Test[A-Za-z0-9_]+) ]]; then
                COMPREPLY+=(${BASH_REMATCH[1]})
            elif [[ $line =~ ^(async[[:space:]]+)?def[[:space:]]+(test_[A-Za-z0-9_]+) ]]; then
                COMPREPLY+=(${BASH_REMATCH[2]})
            fi
        done 2>/dev/null <"$file"
        ((!${#COMPREPLY[@]})) ||
            COMPREPLY=($(compgen -P "$file::" -W '${COMPREPLY[@]}' \
                -- "${cur##*.py:?(:)}"))
        __ltrim_colon_completions "$cur"
        return
    fi

    _filedir py
} &&
    complete -F _pytest pytest pytest-2 pytest-3 py.test py.test-2 py.test-3

# ex: filetype=sh
