#------------------------------------------------------------------------------
#   This file is part of the Code_Saturne Kernel, element of the
#   Code_Saturne CFD tool.
#
#   Copyright (C) 2009 EDF S.A., France
#
#   The Code_Saturne Kernel is free software; you can redistribute it
#   and/or modify it under the terms of the GNU General Public License
#   as published by the Free Software Foundation; either version 2 of
#   the License, or (at your option) any later version.
#
#   The Code_Saturne Kernel is distributed in the hope that it will be
#   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
#   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public Licence
#   along with the Code_Saturne Kernel; if not, write to the
#   Free Software Foundation, Inc.,
#   51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#-------------------------------------------------------------------------------

# Batch completion script for:
# - "code_saturne" user Python script
# - "cs_solver" binary executable

_code_saturne() {

    local cur prev opt cmds cmdOpts opt i

    COMPREPLY=()

    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    # Possible commands except "help", as given by "code_saturne help"
    cmds="check_consistency check_mesh plot_probes"
    cmds="${cmds} compile config create gui info"

    # Help and Case options
    local helpOpts="-h --help"
    local caseOpts="-c --case"

    # Readers and guides
    local readers="evince gpdf kpdf xpdf acroread"
    local guides="refcard theory tutorial user"

    # Boolean values
    local isCmd=0
    local isOptCase=0

    if [[ ${COMP_CWORD} -eq 1 ]]; then
        COMPREPLY=( $(compgen -W "help ${cmds}" -- ${cur}) )
        return 0
    fi

    # Certain tokens preclude further activity
    if [[ ${prev} == @(-h|--help|-v|--version) ]]; then
        return 0
    fi

    # Check if previous token is a command or not
    [[ ${prev} == @(${cmds// /|}) ]] && isCmd=1

    # Parse arguments and set various variables about what was found.
    #
    # cmd: the current command if available
    local cmd=${COMP_WORDS[1]}

    # Check options depending on the command and the previous token
    case ${cmd} in
        help)
            case ${prev} in
                help)
                    COMPREPLY=( $(compgen -W "${cmds}" -- ${cur}) )
                    return 0
                    ;;
                *) return 0;;
            esac
            ;;
        check_consistency)
            case ${prev} in
                -p|--param)  _filedir; return 0;;
                -s|--source) _filedir -d; return 0;;
                -n|--nproc)  COMPREPLY=( ); return 0;;
                *) cmdOpts="-p --param -s --source -n --nproc";;
            esac
            ;;
        compile)
            case ${prev} in
                -d|--dest)   _filedir -d; return 0;;
                -s|--source) _filedir -d; return 0;;
                *) cmdOpts="-t --test -f --force -s --source -d --dest \
                     --opt-libs --syrthes";;
            esac
            ;;
        create)
            case ${prev} in
                -c|--case)     COMPREPLY=( ); return 0;;
                -s|--study)    COMPREPLY=( ); return 0;;
                --nsat|--nsyr) COMPREPLY=( ); return 0;;
                --copy-from)   _filedir -d; return 0;;
                *) cmdOpts="-s --study -c --case -n --nogui --noref --copy-from \
                     --new-runcase --nsat --nsyr -q --quiet -v --verbose";;
            esac
            ;;
        gui)
            case ${prev} in
                -f|--file)  _filedir; return 0;;
                -b|--batch) COMPREPLY=( ); return 0;;
                *) cmdOpts="-f --file -b --batch -n --new -m --matisse \
                     --no-tree -z --no-splash";;
            esac
            ;;
        info)
            case ${prev} in
                -r|--reader)
                    COMPREPLY=( $(compgen -W "${readers}" -- ${cur}) )
                    return 0
                    ;;
                -g|--guide)
                    COMPREPLY=( $(compgen -W "${guides}" -- ${cur}) )
                    return 0
                    ;;
                *) cmdOpts="-r --reader -g --guide --version"
            esac
            ;;
        plot_probes)
            case ${prev} in
                plot_probes) _filedir "dat";;
                *) return 0;;
            esac
            ;;
        *)
            cmdOpts=""
            ;;
    esac

    # Take out options already given
    for (( i=2; i<=$COMP_CWORD-1; ++i ))
    do
        opt=${COMP_WORDS[$i]}

        local optBase

        # Remove leading dashes and arguments
        case $opt in
            --*)    optBase=${opt/=*/} ;;
            -*)     optBase=${opt:0:2} ;;
        esac

        cmdOpts=" $cmdOpts "
        cmdOpts=${cmdOpts/ ${optBase} / }

        # Take out alternatives and mutually exclusives
        case $optBase in
            -b)              cmdOpts=${cmdOpts/ --batch / } ;;
            --batch)         cmdOpts=${cmdOpts/ -b / }
                             cmdOpts=${cmdOpts/ --new / };;
            -c)              cmdOpts=${cmdOpts/ --case / }; isOptcase=1 ;;
            --case)          cmdOpts=${cmdOpts/ -c / }; isOptcase=1 ;;
            -d)              cmdOpts=${cmdOpts/ --dest / } ;;
            --dest)          cmdOpts=${cmdOpts/ -d / } ;;
            -f)              cmdOpts=${cmdOpts/ --file / } ;;
            --file)          cmdOpts=${cmdOpts/ -f / } ;;
            -g)              cmdOpts=${cmdOpts/ --guide / } ;;
            --guide)         cmdOpts=${cmdOpts/ -g / } ;;
            -m)              cmdOpts=${cmdOpts/ --matisse / } ;;
            --matisse)       cmdOpts=${cmdOpts/ -m / } ;;
            -n)
                case ${cmd} in
                    check_consistency) cmdOpts=${cmdOpts/ --nproc / } ;;
                    gui)               cmdOpts=${cmdOpts/ --new / } ;;
                esac ;;
            --new)           cmdOpts=${cmdOpts/ -n / }
                             cmdOpts=${cmdOpts/ --batch / }
                             cmdOpts=${cmdOpts/ --file / } ;;
            --nproc)         cmdOpts=${cmdOpts/ -n / } ;;
            --opt-libs)      cmdOpts=${cmdOpts/ --syrthes / } ;;
            -p)              cmdOpts=${cmdOpts/ --param / } ;;
            --param)         cmdOpts=${cmdOpts/ -p / } ;;
            -q)              cmdOpts=${cmdOpts/ --quiet / } ;;
            --quiet)         cmdOpts=${cmdOpts/ -q / } ;;
            -r)              cmdOpts=${cmdOpts/ --reader / } ;;
            --reader)        cmdOpts=${cmdOpts/ -r / } ;;
            -s)
                case ${cmd} in
                    compile) cmdOpts=${cmdOpts/ --source / } ;;
                    create)  cmdOpts=${cmdOpts/ --study / } ;;
                esac ;;
            --source)        cmdOpts=${cmdOpts/ -s / } ;;
            --study)         cmdOpts=${cmdOpts/ -s / } ;;
            --syrthes)       cmdOpts=${cmdOpts/ --opt-libs / } ;;
            -t)              cmdOpts=${cmdOpts/ --test / } ;;
            --test)          cmdOpts=${cmdOpts/ -t / } ;;
            -v)              cmdOpts=${cmdOpts/ --verbose / } ;;
            --verbose)       cmdOpts=${cmdOpts/ -v / } ;;
        esac

    done

    # Add case options (may appear several times in command line)
    [[ $isOptCase -eq 1 ]] && cmdOpts="${caseOpts} ${cmdOpts}"

    # Add help options for every command but "help"
    [[ $isCmd -eq 1 ]] && cmdOpts="${helpOpts} ${cmdOpts}"


    COMPREPLY=( ${COMPREPLY[@]} $(compgen -W "${cmdOpts}" -- ${cur}) )

}
complete -F _code_saturne code_saturne

# -------------------------------------------------

_cs_solver() {

    local cur prev options i

    COMPREPLY=()

    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    options="--solcom --mpi --mpi-io -q --quality --benchmark --cwf \
             --log --logp -p --param --syr-socket"

    local versOpts="--version"
    local helpOpts="-h --help"

    local allOpts="${helpOpts} ${versOpts} ${options}"


    if [[ ${COMP_CWORD} -eq 1 ]]; then
        COMPREPLY=( $(compgen -W "${allOpts}" -- ${cur}) )
        return 0
    fi

    # Certain tokens preclude further activity
    if [[ ${prev} == @(-h|--help|-v|--version) ]]; then
        return 0
    fi

    case "${prev}" in
        --cwf|--syr-socket) COMPREPLY=( ); return 0;;
        --log)  COMPREPLY=( $(compgen -W "0 1" -- ${cur}) ); return 0;;
        --logp) COMPREPLY=( $(compgen -W "-1 0 1" -- ${cur}) ); return 0;;
        -p|--param) _filedir; return 0;;
    esac

    # Take out options already given
    for (( i=1; i<=$COMP_CWORD-1; ++i ))
    do
        opt=${COMP_WORDS[$i]}

        local optBase

        # Remove leading dashes and arguments
        case $opt in
            --*)    optBase=${opt/=*/} ;;
            -*)     optBase=${opt:0:2} ;;
        esac

        options=" $options "
        options=${options/ ${optBase} / }

        # Take out alternatives and mutually exclusives
        case $optBase in
            --mpi|--mpi-io)  options=${options/ --solcom / } ;;
            -p)              options=${options/ --param / } ;;
            --param)         options=${options/ -p / } ;;
            -q)              options=${options/ --quality / } ;;
            --quality)       options=${options/ -p / } ;;
            --solcom)        options=${options/ --mpi / }
                             options=${options/ --mpi-io / };;
        esac

    done

    COMPREPLY=( $(compgen -W "${options}" -- ${cur}) )

}
complete -F _cs_solver cs_solver
