#!/usr/bin/env bash
set -Eeuo pipefail
umask 077
export PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
export PYTHONDONTWRITEBYTECODE=1
BASE="${ROUTER_OPS_BASE:-/opt/router-ops}"
SOURCE_BASE="${ROUTER_VM130_SOURCE_ROOT:-$BASE}"
BUNDLE_ROOT="${BUNDLE_ROOT:?bundle root required}"
BUNDLE_ZIP="${BUNDLE_ZIP:?bundle zip required}"
BUNDLE_SHA256="${EXPECTED_BUNDLE_SHA256:?bundle sha required}"
RUN_DIR="${ROUTER_DETACHED_RUN_DIR:?detached run dir required}"
CHILD_RESULT="${ROUTER_DETACHED_CHILD_RESULT:-$RUN_DIR/child-result.env}"
SELFTEST="${ROUTER_EXACT_WORKER_SELFTEST:-false}"
INCOMING="${ROUTER_STEP_INCOMING:-/home/ops/incoming}"
TS="$(date -u +%Y%m%d-%H%M%S)"
EVIDENCE="$RUN_DIR/evidence"; REPORT="$RUN_DIR/report"; PAYLOAD="$RUN_DIR/public-payload"
CURRENT="$RUN_DIR/workflow-current.txt"; EVENTS="$RUN_DIR/workflow-events.tsv"; FINAL_ENV="$RUN_DIR/final-result.env"
FINAL_EXTRACT="$RUN_DIR/independent-final-extract"; HELPER="$RUN_DIR/helper"
SOURCE_ENV="$RUN_DIR/vm130-source.env"; PROJECT_ENV="$RUN_DIR/project-source.env"
mkdir -p "$EVIDENCE" "$REPORT" "$PAYLOAD" "$HELPER"; chmod 700 "$EVIDENCE" "$REPORT" "$PAYLOAD" "$HELPER"
tar -xzf "$BUNDLE_ROOT/payload/vm130-workflow-target-package.tar.gz" -C "$HELPER" \
  bin/router-zip-contract bin/router-release-contract lib/router-step-workflow.sh lib/router-core-boundary.sh
source "$HELPER/lib/router-step-workflow.sh"
source "$HELPER/lib/router-core-boundary.sh"
eval "$("$HELPER/bin/router-release-contract" env --root "$BUNDLE_ROOT")"
STEP_ID="$ROUTER_RELEASE_STEP_ID"; REVISION="$ROUTER_RELEASE_REVISION"
FINAL_ROOT="$FINAL_EXTRACT/$STEP_ID"
CURRENT_PHASE=bootstrap; CORE_CHANGE_COMPLETE=false; BACKUP_READY=false; ROLLBACK_STATUS=not_needed; FAILURE_HANDLED=false
STEP_REPORT_URL=not_published; LATEST_ARCHIVE=not_created; LATEST_ARCHIVE_SHA256=unknown
router_step_workflow_init "$CURRENT" "$EVENTS" preflight independent_extract mandatory_tests apply source_publication project_source report_build report_publish archive
write_child() {
 local result="$1" rc="$2" tmp="${CHILD_RESULT}.tmp.$$"
 { echo "RUNNER_STEP_RESULT=$([[ $rc -eq 0 ]] && echo PASS || echo STOP)"; echo "RESULT=$result"; echo "REVISION=$REVISION"; echo "RUN_DIR=$RUN_DIR"; echo "STEP_REPORT_URL=$STEP_REPORT_URL"; echo "LATEST_ARCHIVE=$LATEST_ARCHIVE"; echo "LATEST_ARCHIVE_SHA256=$LATEST_ARCHIVE_SHA256"; echo "CORE_CHANGE_COMPLETE=$CORE_CHANGE_COMPLETE"; echo "ROLLBACK_STATUS=$ROLLBACK_STATUS"; echo "CHILD_RC=$rc"; } > "$tmp"
 chmod 600 "$tmp"; mv -f "$tmp" "$CHILD_RESULT"
}
archive_latest() {
 set +e
 router_step_archive_latest_python "$BASE" "$INCOMING" "$TS" > "$EVIDENCE/latest-archive.log" 2>&1
 local rc=$?
 set -e
 cat "$EVIDENCE/latest-archive.log" || true
 if [[ $rc -eq 0 ]]; then
  LATEST_ARCHIVE="$(awk -F= '$1=="LATEST_ARCHIVE"{print substr($0,index($0,"=")+1)}' "$EVIDENCE/latest-archive.log"|tail -n1)"
  LATEST_ARCHIVE_SHA256="$(awk -F= '$1=="LATEST_ARCHIVE_SHA256"{print $2}' "$EVIDENCE/latest-archive.log"|tail -n1)"
 fi
}
rollback_now() {
 [ "$BACKUP_READY" = true ] || return 0
 [ "$CORE_CHANGE_COMPLETE" != true ] || return 0
 set +e
 BUNDLE_ROOT="$FINAL_ROOT" ROUTER_OPS_BASE="$BASE" "$FINAL_ROOT/scripts/rollback-vm130-workflow.sh" "$RUN_DIR" > "$EVIDENCE/rollback.log" 2>&1
 local rc=$?
 set -e
 [[ $rc -eq 0 ]] && ROLLBACK_STATUS=completed || ROLLBACK_STATUS="failed_rc_$rc"
}
publish_stop() {
 local phase="$1" line="$2" rc="$3" command="$4" source_root="$BUNDLE_ROOT"
 [[ -f "$FINAL_ROOT/scripts/build-stop-report.py" ]] && source_root="$FINAL_ROOT"
 python3 "$source_root/scripts/build-stop-report.py" --step-id "$STEP_ID" --phase "$phase" --line "$line" --rc "$rc" --command "$command" --core-complete "$CORE_CHANGE_COMPLETE" --rollback "$ROLLBACK_STATUS" --run-dir "$RUN_DIR" --output "$REPORT" || true
 cp "$source_root/scripts/run-step.sh" "$REPORT/executed-step.sh" 2>/dev/null || true
 cp "$CURRENT" "$REPORT/workflow-current.txt" 2>/dev/null || true
 cp "$EVENTS" "$REPORT/workflow-events.tsv" 2>/dev/null || true
 if [[ "$SELFTEST" == true ]]; then STEP_REPORT_URL="selftest://stop-r20qua2/"; return 0; fi
 set +e
 router_step_publish_payload step050m07r20qua2_r03_vm130_canonical_contract_stop "$REPORT" "$PAYLOAD" "$CURRENT" "$EVENTS" "$FINAL_ENV" \
  "$REPORT/report.txt" report.txt "$REPORT/facts.json" facts.json "$REPORT/facts-public.html" facts-public.html \
  "$REPORT/verify-public.html" verify-public.html "$REPORT/rollback-public.html" rollback-public.html \
  "$REPORT/executed-step.sh" executed-step.sh "$REPORT/workflow-current.txt" workflow-current.txt "$REPORT/workflow-events.tsv" workflow-events.tsv > "$EVIDENCE/stop-publication.log" 2>&1
 set -e
 [[ -f "$FINAL_ENV" ]] && STEP_REPORT_URL="$(awk -F= '$1=="PUBLIC_URL"{print substr($0,index($0,"=")+1)}' "$FINAL_ENV"|tail -n1)"
}
stop() {
 local rc="$1" line="$2" command="$3" phase="${CURRENT_PHASE:-unknown}"
 trap - ERR
 [[ "$FAILURE_HANDLED" == false ]] || exit "$rc"; FAILURE_HANDLED=true
 set +e; router_step_phase_fail "$phase" "line=$line rc=$rc" >/dev/null 2>&1 || true; set -e
 rollback_now || true; publish_stop "$phase" "$line" "$rc" "$command" || true; archive_latest || true
 write_child STOP_R20QUA2_R03_VM130_CANONICAL_BUNDLE_EXECUTION_CONTRACT "$rc"
 echo RESULT=STOP_R20QUA2_R03_VM130_CANONICAL_BUNDLE_EXECUTION_CONTRACT; echo "STOP_PHASE=$phase"; echo "STOP_LINE=$line"; echo "STOP_RC=$rc"; printf 'STOP_COMMAND=%q\n' "$command"; echo "CORE_CHANGE_COMPLETE=$CORE_CHANGE_COMPLETE"; echo "ROLLBACK_STATUS=$ROLLBACK_STATUS"; echo "STEP_REPORT_URL=$STEP_REPORT_URL"; echo "LATEST_ARCHIVE=$LATEST_ARCHIVE"; echo "LATEST_ARCHIVE_SHA256=$LATEST_ARCHIVE_SHA256"; echo "RUN_DIR=$RUN_DIR"
 exit "$rc"
}
trap 'rc=$?; stop "$rc" "$LINENO" "$BASH_COMMAND"' ERR

CURRENT_PHASE=preflight; router_step_phase_begin preflight
if [[ "$SELFTEST" != true ]]; then [[ "$(hostname)" == router-ops && "$(id -u)" -ne 0 ]]; fi
[[ "$(sha256sum "$BUNDLE_ZIP"|awk '{print $1}')" == "$BUNDLE_SHA256" ]]
"$HELPER/bin/router-release-contract" verify --root "$BUNDLE_ROOT" --step "$STEP_ID"
router_step_phase_complete preflight authoritative_release_contract_verified

CURRENT_PHASE=independent_extract; router_step_phase_begin independent_extract
rm -rf "$FINAL_EXTRACT"; mkdir -p "$FINAL_EXTRACT"
"$HELPER/bin/router-zip-contract" verify --zip "$BUNDLE_ZIP" --root "$STEP_ID" --canonical | tee "$EVIDENCE/zip-verify.log"
"$HELPER/bin/router-zip-contract" extract --zip "$BUNDLE_ZIP" --destination "$FINAL_EXTRACT" --root "$STEP_ID" --canonical | tee "$EVIDENCE/zip-extract.log"
(cd "$FINAL_ROOT" && sha256sum -c manifest.sha256) > "$EVIDENCE/final-manifest.log"
"$HELPER/bin/router-release-contract" verify --root "$FINAL_ROOT" --step "$STEP_ID"
router_step_phase_complete independent_extract same_shared_extractor_and_release_contract

CURRENT_PHASE=mandatory_tests; router_step_phase_begin mandatory_tests
: > "$EVIDENCE/mandatory-tests.log"
while IFS= read -r test_name; do
 [[ -n "$test_name" && "$test_name" != \#* ]] || continue
 echo ">>> $test_name" | tee -a "$EVIDENCE/mandatory-tests.log"
 BUNDLE_ROOT="$FINAL_ROOT" BUNDLE_ZIP="$BUNDLE_ZIP" EXPECTED_BUNDLE_SHA256="$BUNDLE_SHA256" \
  ROUTER_EXACT_WORKER_SELFTEST="$SELFTEST" bash "$FINAL_ROOT/tests/$test_name" >> "$EVIDENCE/mandatory-tests.log" 2>&1
done < "$FINAL_ROOT/tests/mandatory.list"
router_step_phase_complete mandatory_tests final_extracted_bundle_and_exact_worker_passed

CURRENT_PHASE=apply; router_step_phase_begin apply
set +e
BUNDLE_ROOT="$FINAL_ROOT" ROUTER_OPS_BASE="$BASE" ROUTER_VM130_SOURCE_ROOT="$SOURCE_BASE" ROUTER_EXACT_WORKER_SELFTEST="$SELFTEST" \
 router_core_boundary_run "$EVIDENCE/apply.log" -- "$FINAL_ROOT/scripts/apply-vm130-workflow.sh" "$ROUTER_RELEASE_TARGET_PACKAGE_SHA256" "$RUN_DIR"
brc=$?
set -e
[[ -f "$RUN_DIR/apply-state.env" ]] && source "$RUN_DIR/apply-state.env"
[[ -f "$RUN_DIR/backup/live-pre-change.tar.gz" ]] && BACKUP_READY=true
CORE_CHANGE_COMPLETE="${ROUTER_CORE_CHANGE_COMPLETE:-${CORE_CHANGE_COMPLETE:-false}}"
[[ $brc -eq 0 && "${ROUTER_CORE_CHILD_RC:-1}" -eq 0 && "$CORE_CHANGE_COMPLETE" == true ]]
ROLLBACK_STATUS=not_needed_core_complete
router_step_phase_complete apply exact_80_file_target_and_shared_selftests_passed

CURRENT_PHASE=source_publication; router_step_phase_begin source_publication
BUNDLE_ROOT="$FINAL_ROOT" ROUTER_OPS_BASE="$BASE" ROUTER_VM130_SOURCE_ROOT="$SOURCE_BASE" ROUTER_EXACT_WORKER_SELFTEST="$SELFTEST" "$FINAL_ROOT/scripts/publish-vm130-source.sh" "$RUN_DIR" "$SOURCE_ENV" | tee "$EVIDENCE/source-publication.log"
grep -Fqx RESULT=PASS_R20QUA2_R03_VM130_SOURCE_PUBLICATION "$SOURCE_ENV"
router_step_phase_complete source_publication fresh_80_file_vm130_source

CURRENT_PHASE=project_source; router_step_phase_begin project_source
BUNDLE_ROOT="$FINAL_ROOT" ROUTER_OPS_BASE="$BASE" ROUTER_EXACT_WORKER_SELFTEST="$SELFTEST" "$FINAL_ROOT/scripts/publish-project-source.sh" "$RUN_DIR" "$SOURCE_ENV" "$PROJECT_ENV" | tee "$EVIDENCE/project-source.log"
grep -Fqx RESULT=PASS_R20QUA2_PROJECT_SOURCE_PUBLICATION "$PROJECT_ENV"
router_step_phase_complete project_source updated_contract_reference

CURRENT_PHASE=report_build; router_step_phase_begin report_build
python3 "$FINAL_ROOT/scripts/build-report.py" "$RUN_DIR" "$REPORT" "$(cat "$FINAL_ROOT/installer.sha256")" "$SOURCE_ENV" "$PROJECT_ENV"
cp "$FINAL_ROOT/scripts/run-step.sh" "$REPORT/executed-step.sh"; cp "$FINAL_ROOT/release-info.json" "$REPORT/release-info.json"; cp "$CURRENT" "$REPORT/workflow-current.txt"; cp "$EVENTS" "$REPORT/workflow-events.tsv"; cp "$EVIDENCE/mandatory-tests.log" "$REPORT/mandatory-tests.log"; cp "$EVIDENCE/zip-verify.log" "$REPORT/zip-verify.log"; cp "$EVIDENCE/apply.log" "$REPORT/apply.log"
router_step_phase_complete report_build complete_pass_payload

CURRENT_PHASE=report_publish; router_step_phase_begin report_publish
if [[ "$SELFTEST" == true ]]; then
 mkdir -p "$BASE/public/r/token/latest/r20qua2-selftest"; printf 'token\n' > "$BASE/public/.router-public-token"; cp "$REPORT/report.txt" "$BASE/public/r/token/latest/r20qua2-selftest/report.txt"; STEP_REPORT_URL=selftest://r20qua2-pass/
else
 router_step_publish_payload step050m07r20qua2_r03_vm130_canonical_bundle_execution_contract "$REPORT" "$PAYLOAD" "$CURRENT" "$EVENTS" "$FINAL_ENV" \
  "$REPORT/report.txt" report.txt "$REPORT/facts.json" facts.json "$REPORT/facts-public.html" facts-public.html "$REPORT/verify.txt" verify.txt "$REPORT/verify-public.html" verify-public.html "$REPORT/rollback-public.html" rollback-public.html "$REPORT/executed-step.sh" executed-step.sh "$REPORT/release-info.json" release-info.json "$REPORT/workflow-current.txt" workflow-current.txt "$REPORT/workflow-events.tsv" workflow-events.tsv "$REPORT/mandatory-tests.log" mandatory-tests.log "$REPORT/zip-verify.log" zip-verify.log "$REPORT/apply.log" apply.log
 STEP_REPORT_URL="$(awk -F= '$1=="PUBLIC_URL"{print substr($0,index($0,"=")+1)}' "$FINAL_ENV"|tail -n1)"
fi
router_step_phase_complete report_publish pass_report_published

CURRENT_PHASE=archive; router_step_phase_begin archive
archive_latest
[[ "$LATEST_ARCHIVE" != not_created && -f "$LATEST_ARCHIVE" ]]
router_step_phase_complete archive latest_python_zip_created
router_step_workflow_mark_complete
trap - ERR
write_child PASS_R20QUA2_R03_VM130_CANONICAL_BUNDLE_EXECUTION_CONTRACT 0
cat "$REPORT/report.txt"; echo "STEP_REPORT_URL=$STEP_REPORT_URL"; echo "LATEST_ARCHIVE=$LATEST_ARCHIVE"; echo "LATEST_ARCHIVE_SHA256=$LATEST_ARCHIVE_SHA256"; echo CORE_CHANGE_COMPLETE=true
