# shellcheck shell=sh disable=SC3043
___x_cmd_job_pool(){
    if [ "$#" -eq 0 ]; then
        ___x_cmd_job_pool help
        return 1
    fi

    local op="${1}"; shift
    case "$op" in
        create)                     ___x_cmd_job_pool_create "$@" ;;
        set_max)                    ___x_cmd_job_pool_set_max "$@" ;;
        get_max)                    ___x_cmd_job_pool_get_max "$@" ;;
        get_active_size)            ___x_cmd_job_pool_get_active_size "$@" ;;

        offer)                      ___x_cmd_job_pool_offer "$@" ;;
        put)                        ___x_cmd_job_pool_put "$@" ;;
        clear)                      ___x_cmd_job_pool_clear "$@" ;;
        wait_until_finished)        ___x_cmd_job_wait_until_finished "$@" ;;
    esac
}

___x_cmd_job_pool_create(){
    eval "export ${1:?Provide queue name}=()"
    eval "export $1_max=${2:-6}"
    export O=$1
}

___x_cmd_job_pool_set_max(){
    eval "export ${O:?Provide queue size}_max=3"
}

___x_cmd_job_pool_get_max(){
    eval "echo \$${O:?Provide queue size}_max"
}

___x_cmd_job_pool_get_active_size(){
    jobs -r | wc -l | tr -d ' '
}

___x_cmd_job_pool_offer(){
    local cur max
    cur=$(jobpool.get_active_size)
    max=$(jobpool.get_max)
    if [ "$cur" -le "$max" ]; then
        ( "$@" ) 1>&1 2>&2 &
        return 0
    fi
    return 1
}

# Will block
___x_cmd_job_pool_put(){
    until jobpool.offer "$@"; do
        sleep 3s;
    done
}

___x_cmd_job_pool_clear(){
    eval "export $1=()"
}

___x_cmd_job_pool_wait_until_finished(){
    local s
    while :; do
        s=$(___x_cmd_job_pool_get_active_size)
        [ "$s" -eq 0 ] && return
        sleep 1s
    done
}
