#!/usr/bin/env bash
set -Eeuo pipefail
umask 077
export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
STEP_ID='STEP_050M07R20QD_VM101_ALWAYS_ON_FALLBACK_MAPPER'
TARGET_PACKAGE_SHA='6c9f2f2097780b27fb9103911051d73ce2d79e33fdd3823726697e13b70ae923'
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BUNDLE_ROOT="${BUNDLE_ROOT:-$SCRIPT_DIR}"; export BUNDLE_ROOT
BASE="${ROUTER_OPS_BASE:-/opt/router-ops}"
CONTRACT_ROOT="${ROUTER_CONTRACT_ROOT:-/opt/router-ops}"
WORKFLOW_LIB="${ROUTER_STEP_WORKFLOW_LIB:-$CONTRACT_ROOT/lib/router-step-workflow.sh}"
FINALIZER="${ROUTER_STEP_FINALIZE_BIN:-$CONTRACT_ROOT/bin/router-step-finalize}"
SAFE_PAYLOAD="${ROUTER_PUBLIC_SAFE_PAYLOAD_BIN:-$CONTRACT_ROOT/bin/router-public-safe-payload}"
POLICY_LIB="${ROUTER_PUBLICATION_POLICY_LIB:-$CONTRACT_ROOT/lib/router-publication-policy.sh}"
RUN_ID="$(date -u +%Y%m%d-%H%M%S)-$$"
RUN_DIR="${ROUTER_STEP_RUN_DIR:-$BASE/state/step-runs/$STEP_ID/$RUN_ID}"
CURRENT_FILE="$RUN_DIR/workflow-current.txt"; EVENTS_FILE="$RUN_DIR/workflow-events.tsv"; EVIDENCE_DIR="$RUN_DIR/evidence"; REPORT_DIR="$RUN_DIR/report"; PUBLIC_PAYLOAD="$RUN_DIR/public-payload"; FINAL_ENV="$RUN_DIR/finalize.txt"
LOCK_FILE="${ROUTER_STEP_LOCK_FILE:-$BASE/state/locks/${STEP_ID}.lock}"
CURRENT_PHASE=bootstrap; BACKUP_READY=false; CORE_CHANGE_COMPLETE=false; SOURCE_PUBLISH_STARTED=false; VM101_BACKUP_DIR=''
source "$WORKFLOW_LIB"
rollback_now(){
    [ "$BACKUP_READY" = true ] || return 0
    [ "$CORE_CHANGE_COMPLETE" = false ] || return 0
    [ "$SOURCE_PUBLISH_STARTED" = false ] || return 0
    export VM101_BACKUP_DIR
    "$BUNDLE_ROOT/rollback/rollback.sh"
}
publish_stop_report(){
    local phase="$1"
    local line="$2"
    local rc="$3"
    python3 "$BUNDLE_ROOT/scripts/build_stop_report.py" --step-id "$STEP_ID" --phase "$phase" --line "$line" --rc "$rc" --core-complete "$CORE_CHANGE_COMPLETE" --output "$REPORT_DIR" --release-info "$BUNDLE_ROOT/release-info.json" --installer-sha "$BUNDLE_ROOT/installer.sha256" --bundle-manifest "$BUNDLE_ROOT/manifest.sha256" || return 1
    cp "$BUNDLE_ROOT/install.sh" "$REPORT_DIR/executed-step.sh"
    for f in preflight.txt snapshot.txt backup.txt apply.txt source-publish.txt postcheck.txt project-source.txt rollback.txt; do [[ ! -f "$EVIDENCE_DIR/$f" ]] || cp "$EVIDENCE_DIR/$f" "$REPORT_DIR/$f"; done
    local args
    args=("$REPORT_DIR/report.txt" report.txt "$REPORT_DIR/facts.json" facts.json "$REPORT_DIR/facts-public.html" facts-public.html "$REPORT_DIR/verify-public.html" verify-public.html "$REPORT_DIR/rollback-public.html" rollback-public.html "$REPORT_DIR/release-info.json" release-info.json "$REPORT_DIR/installer.sha256" installer.sha256 "$REPORT_DIR/bundle-manifest.sha256" bundle-manifest.sha256 "$REPORT_DIR/executed-step.sh" executed-step.sh)
    for f in preflight.txt snapshot.txt backup.txt apply.txt source-publish.txt postcheck.txt project-source.txt rollback.txt; do [[ ! -f "$REPORT_DIR/$f" ]] || args+=("$REPORT_DIR/$f" "$f"); done
    ROUTER_PUBLICATION_POLICY_LIB="$POLICY_LIB" "$SAFE_PAYLOAD" "$PUBLIC_PAYLOAD" "${args[@]}" || return 1
    "$FINALIZER" --label step050m07r20qd_vm101_always_on_fallback_mapper_source_profile_continuation --payload-dir "$PUBLIC_PAYLOAD" --workflow-current "$CURRENT_FILE" --workflow-events "$EVENTS_FILE" --output-env "$FINAL_ENV" --expect-kind step-report
}
stop(){
    local line="$1"
    local rc="$2"
    trap - ERR
    if [[ "${BASHPID:-$$}" != "$$" ]]; then exit "$rc"; fi
    set +e
    local phase="${CURRENT_PHASE:-unknown}"
    [[ ! -f "$CURRENT_FILE" ]] || router_step_phase_fail "$phase" "line=$line rc=$rc" >/dev/null 2>&1 || true
    rollback_now > "$EVIDENCE_DIR/rollback.txt" 2>&1 || true
    publish_stop_report "$phase" "$line" "$rc" || true
    echo RESULT=STOP_R20QD_VM101_ALWAYS_ON_FALLBACK_MAPPER
    echo "STOP_PHASE=$phase"; echo "STOP_LINE=$line"; echo "STOP_RC=$rc"; echo "CORE_CHANGE_COMPLETE=$CORE_CHANGE_COMPLETE"
    if [ "$CORE_CHANGE_COMPLETE" = true ]; then echo RUNTIME_IMPACT=source_profile_only; else echo RUNTIME_IMPACT=none_or_rolled_back; fi
    echo CORE_CHANGE_REPEATED=false; echo TARGET_INSTALLER_RERUN=false; echo LIVE_RUNTIME_REAPPLIED=false; echo NFT_APPLY_DURING_STEP=false; echo VM100_MUTATED=false; echo LIVE_SLOT_FAILURE_INJECTED=false
    exit "$rc"
}
trap 'stop "$LINENO" "$?"' ERR
mkdir -p "$RUN_DIR" "$EVIDENCE_DIR" "$REPORT_DIR" "$PUBLIC_PAYLOAD" "$(dirname "$LOCK_FILE")"
exec 9>"$LOCK_FILE"; flock -n 9
router_step_workflow_init "$CURRENT_FILE" "$EVENTS_FILE" preflight snapshot backup apply source_publish postcheck project_source report_build
CURRENT_PHASE=preflight; router_step_phase_begin preflight
"$BUNDLE_ROOT/scripts/preflight.sh" "$EVIDENCE_DIR" | tee "$EVIDENCE_DIR/preflight-main.txt"
grep -Fqx RESULT=PASS_R20QD_CONTINUATION_PREFLIGHT "$EVIDENCE_DIR/preflight-main.txt"
router_step_phase_complete preflight completed_runtime_and_missing_managed_paths_verified
CURRENT_PHASE=snapshot; router_step_phase_begin snapshot
if [[ -n "${ROUTER_R20QD_CONT_SNAPSHOT_FIXTURE:-}" ]]; then cat "$ROUTER_R20QD_CONT_SNAPSHOT_FIXTURE"; else "$BUNDLE_ROOT/scripts/snapshot.sh"; fi | tee "$EVIDENCE_DIR/snapshot.txt"
grep -Fqx RESULT=PASS_R20QD_CONTINUATION_SNAPSHOT "$EVIDENCE_DIR/snapshot.txt"
router_step_phase_complete snapshot source_profile_continuation_checkpoint_ready
CURRENT_PHASE=backup; router_step_phase_begin backup
if [[ -n "${ROUTER_R20QD_CONT_BACKUP_FIXTURE:-}" ]]; then cat "$ROUTER_R20QD_CONT_BACKUP_FIXTURE"; else "$BUNDLE_ROOT/scripts/backup-run.sh" "$RUN_ID"; fi | tee "$EVIDENCE_DIR/backup.txt"
grep -Fqx RESULT=PASS_R20QD_CONTINUATION_VM101_BACKUP "$EVIDENCE_DIR/backup.txt"
VM101_BACKUP_DIR="$(awk -F= '$1=="VM101_BACKUP_DIR"{print substr($0,index($0,"=")+1)}' "$EVIDENCE_DIR/backup.txt"|tail -1)"; [[ -n "$VM101_BACKUP_DIR" ]]; BACKUP_READY=true
router_step_phase_complete backup source_profile_and_runtime_immutability_baseline_saved
CURRENT_PHASE=apply; router_step_phase_begin apply
if [[ -n "${ROUTER_R20QD_CONT_APPLY_FIXTURE:-}" ]]; then cat "$ROUTER_R20QD_CONT_APPLY_FIXTURE"; else "$BUNDLE_ROOT/scripts/transfer-and-apply.sh" "$VM101_BACKUP_DIR"; fi | tee "$EVIDENCE_DIR/apply.txt"
grep -Fqx RESULT=PASS_R20QD_CONTINUATION_SOURCE_PROFILE_APPLY "$EVIDENCE_DIR/apply.txt"
grep -Fqx SOURCE_PROFILE_UPDATED=true "$EVIDENCE_DIR/apply.txt"
grep -Fqx CORE_CHANGE_REPEATED=false "$EVIDENCE_DIR/apply.txt"
grep -Fqx LIVE_RUNTIME_REAPPLIED=false "$EVIDENCE_DIR/apply.txt"
CORE_CHANGE_COMPLETE=true
router_step_phase_complete apply machine_git_profile_extended_without_runtime_reapply
CURRENT_PHASE=source_publish; SOURCE_PUBLISH_STARTED=true; router_step_phase_begin source_publish
if [[ -n "${ROUTER_R20QD_CONT_SOURCE_PUBLISH_FIXTURE:-}" ]]; then cat "$ROUTER_R20QD_CONT_SOURCE_PUBLISH_FIXTURE"; else "$BUNDLE_ROOT/scripts/source-publish.sh"; fi | tee "$EVIDENCE_DIR/source-publish.txt"
grep -Eq '^RESULT=PASS_ROUTER_MACHINE_CLOSE$|^RESULT=PASS_R20QD_CONTINUATION_SOURCE_PUBLISH_FIXTURE$' "$EVIDENCE_DIR/source-publish.txt"
grep -Eq '^(GIT_FILE_COUNT|VM101_GIT_SOURCE_FILE_COUNT|MANAGED_FILE_COUNT|TRACKED_FILE_COUNT)=39$' "$EVIDENCE_DIR/source-publish.txt"
! grep -Fqx COMMIT=1c2c08296d95c1c8a2bbd0db11ed967b981a5f6d "$EVIDENCE_DIR/source-publish.txt"
router_step_phase_complete source_publish final_vm101_machine_git_39_files_committed_and_published
CURRENT_PHASE=postcheck; router_step_phase_begin postcheck
if [[ -n "${ROUTER_R20QD_CONT_POSTCHECK_FIXTURE:-}" ]]; then cat "$ROUTER_R20QD_CONT_POSTCHECK_FIXTURE"; else "$BUNDLE_ROOT/scripts/postcheck-run.sh" "$EVIDENCE_DIR/preflight-main.txt" "$EVIDENCE_DIR/source-publish.txt"; fi | tee "$EVIDENCE_DIR/postcheck.txt"
grep -Fqx RESULT=PASS_R20QD_CONTINUATION_POSTCHECK "$EVIDENCE_DIR/postcheck.txt"
grep -Fqx NEW_MANAGED_PATHS_TRACKED=true "$EVIDENCE_DIR/postcheck.txt"
grep -Fqx CORE_CHANGE_REPEATED=false "$EVIDENCE_DIR/postcheck.txt"
grep -Fqx TARGET_INSTALLER_RERUN=false "$EVIDENCE_DIR/postcheck.txt"
grep -Fqx LIVE_RUNTIME_REAPPLIED=false "$EVIDENCE_DIR/postcheck.txt"
grep -Fqx NFT_APPLY_DURING_STEP=false "$EVIDENCE_DIR/postcheck.txt"
router_step_phase_complete postcheck final_source_and_runtime_immutability_verified
CURRENT_PHASE=project_source; router_step_phase_begin project_source
if [[ -n "${ROUTER_R20QD_CONT_PROJECT_SOURCE_FIXTURE:-}" ]]; then cat "$ROUTER_R20QD_CONT_PROJECT_SOURCE_FIXTURE"; else "$BUNDLE_ROOT/scripts/publish-project-source.sh" "$EVIDENCE_DIR/source-publish.txt" "$EVIDENCE_DIR/postcheck.txt" "$RUN_DIR/project-source"; fi | tee "$EVIDENCE_DIR/project-source.txt"
grep -Fqx RESULT=PASS_R20QD_CONTINUATION_PROJECT_SOURCE_PUBLISH "$EVIDENCE_DIR/project-source.txt"
router_step_phase_complete project_source canonical_continuation_project_source_published
CURRENT_PHASE=report_build; router_step_phase_begin report_build
python3 "$BUNDLE_ROOT/scripts/build_report.py" --preflight "$EVIDENCE_DIR/preflight-main.txt" --snapshot "$EVIDENCE_DIR/snapshot.txt" --backup "$EVIDENCE_DIR/backup.txt" --apply "$EVIDENCE_DIR/apply.txt" --source-publish "$EVIDENCE_DIR/source-publish.txt" --postcheck "$EVIDENCE_DIR/postcheck.txt" --project-source "$EVIDENCE_DIR/project-source.txt" --output "$REPORT_DIR" --release-info "$BUNDLE_ROOT/release-info.json" --installer-sha "$BUNDLE_ROOT/installer.sha256" --bundle-manifest "$BUNDLE_ROOT/manifest.sha256"
python3 -m json.tool "$REPORT_DIR/facts.json" >/dev/null
cp "$BUNDLE_ROOT/install.sh" "$REPORT_DIR/executed-step.sh"
for f in preflight-main.txt snapshot.txt backup.txt apply.txt source-publish.txt postcheck.txt project-source.txt; do cp "$EVIDENCE_DIR/$f" "$REPORT_DIR/${f/preflight-main/preflight}"; done
args=("$REPORT_DIR/report.txt" report.txt "$REPORT_DIR/facts.json" facts.json "$REPORT_DIR/facts-public.html" facts-public.html "$REPORT_DIR/verify-public.html" verify-public.html "$REPORT_DIR/rollback-public.html" rollback-public.html "$REPORT_DIR/release-info.json" release-info.json "$REPORT_DIR/installer.sha256" installer.sha256 "$REPORT_DIR/bundle-manifest.sha256" bundle-manifest.sha256 "$REPORT_DIR/executed-step.sh" executed-step.sh "$REPORT_DIR/preflight.txt" preflight.txt "$REPORT_DIR/snapshot.txt" snapshot.txt "$REPORT_DIR/backup.txt" backup.txt "$REPORT_DIR/apply.txt" apply.txt "$REPORT_DIR/source-publish.txt" source-publish.txt "$REPORT_DIR/postcheck.txt" postcheck.txt "$REPORT_DIR/project-source.txt" project-source.txt)
ROUTER_PUBLICATION_POLICY_LIB="$POLICY_LIB" "$SAFE_PAYLOAD" "$PUBLIC_PAYLOAD" "${args[@]}"
"$FINALIZER" --label step050m07r20qd_vm101_always_on_fallback_mapper_source_profile_continuation --payload-dir "$PUBLIC_PAYLOAD" --workflow-current "$CURRENT_FILE" --workflow-events "$EVENTS_FILE" --output-env "$FINAL_ENV" --expect-kind step-report
router_step_phase_complete report_build final_pass_report_published
trap - ERR
cat "$FINAL_ENV"
cat "$REPORT_DIR/report.txt"
echo BOOTSTRAP_INSTALLER_RC=0
