# This script implements two phases and an auxiliary phase.
# Phase  C: fetch dist-root control.
# Phase  D: fetch per-area control.
# Phase DD: stamp the release time.
#
# This script and 60phase-e.bash are the program's heart.
#
# If $OPT_SUMS, this script sets the following, which carries through to the
# rest of the program:
#
#     ctrl-filepaths.list
#
# This script modifies the following, intialized in 07initialization.bash.
# They carry through to the rest of the program:
#
#     DIST1 MIRROR
#     IS_BACKPORTS (integer)
#

readonly MSGC05=$(gettext\
 'fetching control files to learn what to mirror for Debian %s %s')
readonly MSGC15=$(gettext\
 'control files fetched: prepared to mirror Debian %s %s')
readonly MSGD30=$(gettext 'scanning %s'"'"'s Release file')
readonly MSGD40=$(gettext 'because the release'"'"'s minor version is %s, skipping prefetch of %s')
readonly MSGDD60a='the backports release must lie in the past according to the system'"'"'s clock'
readonly MSGDD60b='and, also, must precede or equal the regular release'
readonly MSGDD60=$(gettext "$MSGDD60a $MSGDD60b")
readonly MSGDD70=$(gettext\
 'an internal glitch regarding timestamps has arisen regarding the regular release')
readonly MSGDD80=$(gettext\
 'the regular release must lie in the past according to the system'"'"'s clock')

if (($OPT_PHASE_C)); then

    inform "$(printf "$MSGC05..." "$VER" "$DIST_CODENAME")"
    mkdir -p$V -- "$TARGET"

fi # phase C continues below, though

declare ROOTFPS SED_SCRIPT FP1 FP2
declare RFPS ZFPS SHA256 SIZE FILEPATH DIR BASE PREFETCH_FPS
pushd >/dev/null "$TARGET"
for DIST1 in\
    "$DIST" $( (($OPT_BACKPORTS)) && printf '%s' "$DIST_BACKPORTS" )
do

    # Appraise whether backports.
    IS_BACKPORTS=1; [ "$DIST1" = "$DIST" ] && IS_BACKPORTS=0
    MIRROR="$MIRROR_PRIMARY";\
     (($IS_BACKPORTS)) && MIRROR="$SNAPSHOT_SERVICE"

    (($IS_BACKPORTS && $OPT_PHASE_B)) && execute_phase_B

    # ---------------------------------------------------------------------
    if (($OPT_PHASE_C)); then

        while true; do
            # Fetch dist-root control. (Note: in dist-root-ctrl.list,
            # a leading '!' indicates that backports lacks the
            # named control.)
            ROOTFPS=''
            SED_SCRIPT='s/^!//;p'; (($IS_BACKPORTS)) && SED_SCRIPT='/^!/!p'
            for FP1 in $(
                sed -rn -- "$SED_SCRIPT" $LIST_DIR/dist-root-ctrl.list
            ); do
                ROOTFPS+=" dists/$DIST1/$FP1"
            done
            recursively_fetch $ROOTFPS # purposely unquoted
            (($IS_BACKPORTS)) && break
            # For the regular archive only, fetch dist-root control again,
            # just in case a new Debian release happens to have arrived
            # during the last fetch.
            if [ -e "$TMPDIR/zzz-duplicate" ]; then
                # Ensure that the two dist-root controls are identical.
                diff -rNq -- "zzz-dists" "$TMPDIR/zzz-duplicate" && break
                pause_before_trying
                rm -rf$V -- "$TMPDIR/zzz-duplicate"
            fi
            mv $VV -- "zzz-dists" "$TMPDIR/zzz-duplicate"
        done

    fi # end phase C
    # ---------------------------------------------------------------------
    if (($OPT_PHASE_D)); then

        # List the per-area control files (as introduced by dist-root ctrl)
        # of all areas for later fetching. Also, incidentally, list which
        # of these files shall want later decompression.
        RFPS='' ZFPS=''
        (($OPT_SUMS)) && touch -- $TMPDIR/ctrl-filepaths.list
        ((!$OPT_SUMS)) && inform "$(printf "$MSGD30..." "$DIST1")"
        while read SHA256 SIZE FILEPATH; do
            DIR="$(dirname -- "$FILEPATH")"
            BASE="$(basename -- "$FILEPATH")"
            if is_ctrl_wanted per-area-ctrl.list "$FILEPATH"; then
                RFPS+=" dists/$DIST1/$FILEPATH"
                if (($OPT_SUMS)); then
                    printf '%s\n' "$SHA256  dists/$DIST1/$FILEPATH"\
                    >>$TMPDIR/ctrl-filepaths.list
                else
                    is_ctrl_wanted ctrl-to-decompress.list "$FILEPATH"\
                    && ZFPS+=" dists/$DIST1/$FILEPATH"
                fi
            fi
        done < <(
            sed -rn -- '/^SHA256:\s*$/!d;:b;n;/^ /!q;p;bb'\
            "dists/$DIST1/Release"
        )
        if ((!$OPT_SUMS)); then

            # Note that, below, the arguments to recursively_fetch and
            # decompress are purposely unquoted. Word splitting on
            # whitespace is needed. (Would it not be preferable to
            # avoid word splitting on whitespace? Answer: perhaps, but
            # this a Bash script, not a C++ program. The pathnames
            # handled within the present indentation are relative
            # pathnames that contain no spaces. One could via quotes,
            # escapes, arrays, IFS, temporary files, etc., of course
            # avoid the space-splitting, anyway; but the author has
            # tried that and, in this particular instance, it has
            # seemed to cause more trouble than is worth the coding
            # effort to work around. Space-splitting is simplest.
            # Still, in the unlikely event that the Debian archive ever
            # directly introduced filenames containing spaces -- as
            # opposed to merely packaging such filenames, which the
            # archive already does -- the code would
            # need modification.)

            # Prefetch a few nodes the regular algorithm of this script
            # and of 60phase-e.bash cannot otherwise correctly sequence.
            PREFETCH_FPS=''
            for FP1 in\
                $(eval echo $(<$LIST_DIR/nodes-to-prefetch.list))
            do
                FP2="$FP1"
                if [[ "$FP1" = :* ]]; then
                    # At minor version 0 of the release, skip the prefetch of
                    # certain nodes absent at minor version 0.  (The node list
                    # marks these nodes by prepending ':'.)
                    FP2="${FP1#:}"
                    if [ "$MINOR_VER" = 0 ]; then
                        inform $(printf "$MSGD40" "$MINOR_VER" "$FP2")
                        continue
                    fi
                fi
                [[ "$FP2" = dists/$(printf '%q' "$DIST1")?(/*) ]]\
                && PREFETCH_FPS+=" $FP2"
            done
            [ -n "$PREFETCH_FPS" ] && recursively_fetch $PREFETCH_FPS

            # Fetch the earlier-listed per-area control files, all areas.
            recursively_fetch $RFPS

            # Decompress.
            [ -n "$ZFPS" ] && decompress $ZFPS

        fi

    fi # end phase D
    # ---------------------------------------------------------------------
    if (($OPT_PHASE_DD)); then
        # Stamp the release time. (The following if-then-else-fi depends on
        # the enclosing loop to treat backports last.)
        if (($IS_BACKPORTS)); then
            stamp_per_release "$TMPDIR/backports.stamp"\
             "dists/$DIST1/Release"
            [\
                     "$TMPDIR/backports.stamp" -ot "$TMPDIR/now.stamp"\
                -a ! "$TMPDIR/backports.stamp" -nt "$TMPDIR/release.stamp"\
            ] || die "$MSGDD60"
            ((!$OPT_PHASE_B)) || ! [\
                   "$TMPDIR/release.stamp" -ot "$TMPDIR/phb-release.stamp"\
                -o "$TMPDIR/release.stamp" -nt "$TMPDIR/phb-release.stamp"\
            ] || die "$MSGDD70"
        else
            stamp_per_release "$TMPDIR/release.stamp"\
             "dists/$DIST1/Release"
            [ "$TMPDIR/release.stamp" -ot "$TMPDIR/now.stamp" ]\
            || die "$MSGDD80"
        fi
    fi # end phase DD
    # ---------------------------------------------------------------------

done
popd >/dev/null

(($OPT_PHASE_C)) && inform "$(printf "$MSGC15" "$VER" "$DIST_CODENAME")"

true

