# This script sets the following, which carry through to the rest of the
# program:
#
#     LANG TZ TEXTDOMAIN TEXTDOMAINDIR (all exported)
#
# The script also introduces these, whose values are however finalized only
# by 07initialization.bash:
#
#     TMPDIR (exported)
#     DO_NOT_INFORM_TO_STDOUT (integer, not exported)
#
# The script makes these functions (which are defined here rather than in
# in 1{0..9}*.bash because the program needs early access to them)
# available to the rest of the program:
#
#     inform        [TEXT...]
#     inform_stderr [TEXT...]
#     warn          [TEXT...]
#     die           [TEXT...]
#     print_bar
#     do_lack_spaces                     [STRING...]
#     function are_acceptable_langs      [STRING...]
#     function are_acceptable_filepaths  [STRING...]
#     function are_acceptable_names      [STRING...]
#     forbid_spaces                      [STRING...]
#     require_langs_to_be_acceptable     [STRING...]
#     require_filepaths_to_be_acceptable [STRING...]
#     require_names_to_be_acceptable     [STRING...]
#
# The script defines the symbol FINDX which, though formally a readonly
# variable, is used by the rest of the program as it were a function:
#
#     "$FINDX" PREOPTS POSTOPTS [BASE...]
#
# The script also sets the program a general exit trap.

# Set up the environment to tell time in UTC and to translate messages to
# the user's language.
export LANG='C.UTF-8'
export TZ='UTC'
readonly LANG TZ
. gettext.sh
readonly TEXTDOMAIN='mirrorrib' TEXTDOMAINDIR="$SCRIPT_DIR/../../locale"
export TEXTDOMAIN TEXTDOMAINDIR

# These are defined here but are not finalized until 07initialization.bash.
export TMPDIR=''
declare -i DO_NOT_INFORM_TO_STDOUT=0 # note: not exported

# Define functions to inform the user.
function inform {
    (($DO_NOT_INFORM_TO_STDOUT)) || printf '%s: %s\n' "$NAME" "$*"
    return 0
}
function inform_stderr { printf >&2 '%s: %s\n' "$NAME" "$*"; true; }
readonly WARNING_WORD=$(gettext 'warning') ERROR_WORD=$(gettext 'error')
function warn {
    printf >&2 '%s %s: %s\n' "$NAME" "$WARNING_WORD" "$*"
    return 0
}
function die {
    printf >&2 '%s %s: %s\n' "$NAME" "$ERROR_WORD" "$*"
    exit 1
}
# [Following the advice of man-pages(7), the maintainer prefers to restrict
# most lines of code to 75 columns at the widest. Still, admittedly, the
# following, HALF_BAR circumlocution to remain within the 75 is a
# little awkward.]
readonly HALF_BAR='---------------------------------------'
function print_bar {
    printf '%s%s%s\n' "$HALF_BAR" "$HALF_BAR" '-'
    return 0
}
readonly -f inform inform_stderr warn die print_bar

# Check the formats of various strings.
function do_lack_spaces {
    local A
    for A; do
        [[ "$A" = *[[:space:]]* ]] && return 1
    done
    return 0
}
function are_acceptable_langs {
    local LANG1
    for LANG1; do
        [[ "$LANG1" = +([[:alnum:]_@]) ]] || return 1
    done
    return 0
}
function are_acceptable_impl {
    local P="$1"; shift
    local A
    for A; do
        if [ -z "$A" ] || ! sed <<<"$A" -rn "\\%[$P\\n\\o000]%q1"; then
            return 1;
        fi
    done
    return 0
}
function are_acceptable_filepaths { are_acceptable_impl '' "$@"; }
function are_acceptable_names { are_acceptable_impl '/' "$@"; }
readonly -f are_acceptable_langs are_acceptable_impl\
 are_acceptable_filepaths are_acceptable_names

# Enforce the formats of various strings.
readonly HLTD_MESSAGE=$(gettext '%s do not appear to be languages')
function require_langs_to_be_acceptable {
    are_acceptable_langs "$@" || die "$(printf "$HLTD_MESSAGE" "$*")"
    return 0
}
readonly DLS_MSG=$(gettext\
 'a name that must not include a space, includes one')
function forbid_spaces {
    do_lack_spaces "$@" || die "$DLS_MSG"
    return 0
}
readonly HRTD_MSG1='a name that has an embedded null [\0]'
readonly HRTD_MSG2='or line feed [\n] character has been encountered;'
readonly HRTD_MSG3='or a name that is not a filepath but has'
readonly HRTD_MSG4='an embedded solidus [/] has been encountered'
readonly HRTD_MESSAGE=$(gettext\
 "$HRTD_MSG1 $HRTD_MSG2 $HRTD_MSG3 $HRTD_MSG4")
function require_filepaths_to_be_acceptable {
    are_acceptable_filepaths "$@" || die "$HRTD_MESSAGE"
    return 0
}
function require_names_to_be_acceptable {
    are_acceptable_names "$@" || die "$HRTD_MESSAGE"
    return 0
}
readonly -f require_langs_to_be_acceptable\
 require_filepaths_to_be_acceptable require_names_to_be_acceptable

# Introduce the alternate interface to find(1).
readonly FINDX="$LIB_DIR/utilities/findx"

# Trap all exits.
function handle_exit_trap {
    if [ -n "$TMPDIR" ]; then
        if (($LEAVE_TEMP_DATA_BEHIND)); then
            local HET_M1 HET_M2 HET_M3 HET_MESSAGE
            readonly HET_M1='finishing (or exiting),'
            readonly HET_M2='but leaving behind temporary data files'
            readonly HET_M3='for the user'"'"'s inspection in %s'
            readonly HET_MESSAGE="$HET_M1 $HET_M2 $HET_M3"
            inform_stderr\
             "$(printf "$(gettext "$HET_MESSAGE")\n" "$TMPDIR")"
        else
            rm -rf -- "$TMPDIR"
        fi
    fi
    true
}
trap handle_exit_trap EXIT
true

