function program_installed {
    local return_=1

    type $1 >/dev/null 2>&1 || { local return_=0; }

    echo "$return_"
}

function list_processes() {
    # List all processes matching the given process name string
    ps aux | grep $(whoami) | grep -i "$1" | grep -v grep
}

function kill_all() {
    # Kill all processes matching the given process name string
    if [ ! "$1" ]; then
        echo "kill_all requires a process name to kill all instances of"
        return 1
    fi
    kill_flag=15
    if [ "$15" ]; then
        kill_flag="$15"
    fi

    count=$(list_processes "$1" | wc -l)

    echo "Killing $count running processes matching $1"
    kill -"$kill_flag" $(list_processes "$1" | awk '{print $2}')
    
    count=$(list_processes "$1" | wc -l)
    if [ $count -gt 0 ]; then
        echo "$count processes could not be killed"
    fi
}

function ranger-cd() {
    # Make shell cd to ranger directory
    tempfile=$(mktemp)
    ranger --choosedir="$tempfile" "${@:-$(pwd)}" < $TTY
    test -f "$tempfile" &&
    if [ "$(cat -- "$tempfile")" != "$(echo -n `pwd`)" ]; then
        cd $(cat $tempfile)
    fi
    zle reset-prompt
    printf '\n'
    rm -f -- "$tempfile"
}

function terminal-clock() {
    tty-clock -tcb < $TTY
    zle reset-prompt
    printf '\n'
}

function check_dotfiles_version {
    # Check if the version of the dotfiles directory is the latest version
    # Return 0 if repo is present and the latest version
    # Return 1 if the repo is not present
    # Return 2 if the repo is behind the remote
    # Return 3 if the repo is ahead of the remote
    # Return 4 if the repo has diverged from the remote
    # Return 5 if DOTFILES_DIR is not set
    if [ -z $DOTFILES_DIR ]; then
        return 5
    fi

    if [ ! -d $DOTFILES_DIR ]; then
        return 2
    fi

    pushd $DOTFILES_DIR > /dev/null

    # TODO: This may be gitbox
    git fetch origin > /dev/null
    UPSTREAM=${1:-'@{u}'}
    LOCAL=$(git rev-parse @)
    REMOTE=$(git rev-parse "$UPSTREAM")
    BASE=$(git merge-base @ "$UPSTREAM")

    popd > /dev/null

    if [[ $LOCAL = $REMOTE ]]; then
        return 0
    elif [[ $LOCAL = $BASE ]]; then
        return 2
    elif [[ $REMOTE = $BASE ]]; then
        return 3
    else
        return 4
    fi
}

function set_python_roots {
    declare -ag PYTHON_ROOTS=()
    if [ -d $HOME/.local/lib/ ]; then
        for directory in $(echo $HOME/.local/lib/python*); do
            PYTHON_ROOTS+=($directory)
        done
    fi
    if [ -d $HOME/.local/share/pipx/venvs/powerline-status/lib/ ]; then
        for directory in $(echo $HOME/.local/share/pipx/venvs/powerline-status/lib/python*); do
            PYTHON_ROOTS+=($directory)
        done
    fi
    if [ -d $HOME/.local/pipx/venvs/powerline-status/lib/ ]; then
        for directory in $(echo $HOME/.local/pipx/venvs/powerline-status/lib/python*); do
            PYTHON_ROOTS+=($directory)
        done
    fi
    if [ -d /usr/lib/ ]; then
        for directory in $(echo /usr/lib/python*); do
            PYTHON_ROOTS+=($directory)
        done
    fi
    if [ -d /usr/local/lib/ ]; then
        # TODO: Make this not print warnings when the directory doesn't exit
        for directory in $(echo /usr/local/lib/python*); do
            PYTHON_ROOTS+=($directory)
        done
    fi
}

function set_powerline_bash_sources {
    set_python_roots
    # Powerline plugin from distribution agnostic install directory
    ## Assemble list of possible sources
    declare -ag POWERLINE_BASH_SOURCES=()
    if [[ -a $POWERLINE_ROOT/bindings/bash/powerline.sh ]]; then
        # Prefer user-set powerline directory
        POWERLINE_BASH_SOURCES+=$POWERLINE_ROOT/bindings/bash/powerline.sh
    fi
    # If $POWERLINE_ROOT not set or set incorrectly, try default locations
    for index in ${!PYTHON_ROOTS[@]}; do
        directory="${PYTHON_ROOTS[index]}"
        if [ -d "$directory" ]; then
            POWERLINE_BASH_SOURCES+=("$directory"/site-packages/powerline/bindings/bash/powerline.sh)
            POWERLINE_BASH_SOURCES+=("$directory"/dist-packages/powerline/bindings/bash/powerline.sh)
        fi
    done
}
