# Here are defined functions relating to fetching over the network (and, in
# one case, relating to the avoidance of such fetching):
#
#     pause_before_retrying
#     run_by_batch [--persist] CMD PRE-ARGS ARGS-FILE POST-ARGS [PREFIX]
#     wget_insist              OPTIONS [FILEn...]
#     copy_locally_available   ROSTER0
#
# See 10function-definitions.bash for general notes that are relevant here.

readonly F14_PBR_M1a='to mitigate or avoid abuse of the service'
readonly F14_PBR_M1b='over the network, pausing %d seconds before retrying'
readonly F14_PBR_M1=$(gettext "$F14_PBR_M1a $F14_PBR_M1b")
readonly F14_PBR_M2a='press ctrl-C to abandon the attempt'
readonly F14_PBR_M2b='and exit the program'
readonly F14_PBR_M2=$(gettext "$F14_PBR_M2a $F14_PBR_M2b")
readonly F14_PBR_M3=$(gettext 'retrying now')
function pause_before_retrying {
    inform "$(printf "$F14_PBR_M1 ($F14_PBR_M2)" "$SLEEP_DURATION")"
    sleep $SLEEP_DURATION
    inform "$F14_PBR_M3..."
    return 0
}
readonly -f pause_before_retrying

# Some commands can accept only a limited number of arguments on their command
# lines, yet it can be inefficient to invoke such a command per argument. As a
# compromise, this function invokes a command once per $BATCH_SIZE arguments.
# (If the number of arguments is moderate, not exceeding $BATCH_SIZE, then this
# function merely invokes the command once in the normal way.)
#
# The ARGS-FILE is to give one argument per line.
#
# (GNU split *might* instead have been used. Whether that would have been
# better is unknown.)
#
# usage: run_by_batch [--persist] CMD PRE-ARGS ARGS-FILE POST-ARGS [PREFIX]
readonly F14_RBB_MSG1='running %s on a %d-record batch'
readonly F14_RBB_MSG2='of the %d remaining records,'
readonly F14_RBB_MSG3='the batch consisting of these'
readonly F14_RBB_MSG=$(gettext "$F14_RBB_MSG1 $F14_RBB_MSG2 $F14_RBB_MSG3")
function run_by_batch {
    local RBB_DO_PERSIST
    declare -i RBB_DO_PERSIST=0;\
     [ $1 = '--persist' ] && shift && RBB_DO_PERSIST=1
    readonly RBB_DO_PERSIST
    local RBB_PREFIX=''; (($# >= 5)) && RBB_PREFIX=$5
    readonly RBB_PREFIX
    local RBB_DATA RBB_BATCH_DATA RBB_EXTRA_DATA
    readonly RBB_DATA=$(mktemp)
    readonly RBB_BATCH_DATA=$(mktemp)
    readonly RBB_EXTRA_DATA=$(mktemp)
    local RBB_SIZE RBB_SIZE1 RBB_IS_FIRST
    declare -i RBB_SIZE RBB_SIZE1 RBB_IS_FIRST
    cat >"$RBB_EXTRA_DATA" -- "$3"
    while true; do
        cat >"$RBB_DATA" -- "$RBB_EXTRA_DATA"
        RBB_SIZE=$(cat -- "$RBB_DATA" | wc -l)
        RBB_SIZE1=$RBB_SIZE;\
         (($RBB_SIZE1 > $BATCH_SIZE)) && RBB_SIZE1=$BATCH_SIZE
        (($RBB_SIZE1)) || break
        head -n$RBB_SIZE1 >"$RBB_BATCH_DATA" -- "$RBB_DATA"
        tail -n+$(($RBB_SIZE1 + 1)) >"$RBB_EXTRA_DATA" -- "$RBB_DATA"
        inform "$(printf "$F14_RBB_MSG:" "$1" "$RBB_SIZE1" "$RBB_SIZE")"
        print_bar
        cat "$RBB_BATCH_DATA"
        print_bar
        until {
            eval $1 $2 $(
                {
                    RBB_IS_FIRST=1
                    while read; do
                        (($RBB_IS_FIRST)) || echo -n ' '
                        echo -n "'"
                        (($RBB_IS_FIRST))\
                         && { printf '%s' "$RBB_PREFIX"; RBB_IS_FIRST=0; }
                        printf '%s'"'" "$REPLY"
                    done
                } <"$RBB_BATCH_DATA"
            ) $4
        } || ((!$RBB_DO_PERSIST)); do pause_before_retrying; done
        print_bar
    done
    rm -f -- "$RBB_DATA" "$RBB_BATCH_DATA" "$RBB_EXTRA_DATA"
    return 0
}
readonly -f run_by_batch

# This function runs wget insistently. Should wget fail,
# files are deleted and wget is tried again.
#
# usage: wget_insist OPTIONS [FILEn...]
#
# The OPTIONS must be passed as a single string.
function wget_insist {
    local WGET_OPTIONS=$1 && shift
    readonly WGET_OPTIONS
    until wget $WGET_OPTIONS -- "$@"; do
        rm -f$V -- $("$FINDX" '' '-maxdepth 0 -type f' "$@")
        pause_before_retrying
    done
    return 0
}
readonly -f wget_insist

# Note: as presently modified, this function is believed to be safe to use even
# outside the pool because it avoids directory links. Inside the pool, the
# function assumes that no disruptive directory links are involved and, thus,
# skips the safety check.
function copy_locally_available {
    local CLA_FILEPATH
    for CLA_FILEPATH in $(<"$1"); do
        if
            ! [ -e "$TARGET/$CLA_FILEPATH" ]\
            && [ -f "$OLD/$CLA_FILEPATH" ]\
            && {
                [[ "$CLA_FILEPATH" = pool/* ]]\
                || [ "$(realpath -e -- "$OLD/$CLA_FILEPATH")"\
                 = "$OLD/$CLA_FILEPATH" ]
            }
        then
            mkdir -p$V -- $(dirname "$TARGET/$CLA_FILEPATH")
            if (($OPT_HARDLINK)); then
                ln $VV  -- "$OLD/$CLA_FILEPATH" "$TARGET/$CLA_FILEPATH"
            else
                cp -a$V -- "$OLD/$CLA_FILEPATH" "$TARGET/$CLA_FILEPATH"
            fi
        fi
    done
    return 0
}
readonly -f copy_locally_available
true

