#!/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}"
INCOMING="${ROUTER_STEP_INCOMING:-/home/ops/incoming}"
SELFTEST="${ROUTER_EXACT_WORKER_SELFTEST:-false}"
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:?run dir required}"
CHILD_RESULT="${ROUTER_DETACHED_CHILD_RESULT:-$RUN_DIR/child-result.env}"
[[ -x "$BASE/bin/router-release-contract" && -x "$BASE/bin/router-zip-contract" ]]
eval "$("$BASE/bin/router-release-contract" env --root "$BUNDLE_ROOT")"
STEP_ID="$ROUTER_RELEASE_STEP_ID"; REVISION="$ROUTER_RELEASE_REVISION"
VM101_GIT_COMMIT='ac678d1b3164e0201d221967fa131e354a211881'
VM101_GIT_TREE='0d00ec84743795ff4dde671e42ac3e77241591ef'
VM101_GIT_FILE_COUNT='58'
SNAPSHOT_NAME='r20qub1-pre-0731-214833'
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"; FINAL_ROOT="$FINAL_EXTRACT/$STEP_ID"
TARGET_PACKAGE="$FINAL_ROOT/$ROUTER_RELEASE_TARGET_PACKAGE_PATH"
GIT_ENV="$RUN_DIR/vm101-git.env"; SOURCE_ENV="$RUN_DIR/vm101-source.env"; MODEL_ENV="$RUN_DIR/vm101-model.env"; METHODS_ENV="$RUN_DIR/vm101-methods.env"; PROJECT_ENV="$RUN_DIR/project-source.env"
PVE_HOST='pve-mgts'; VM101_ADDR='10.71.100.2'; PVE_KEY='/root/.ssh/pve_to_openwrt_mgts_ed25519'
CURRENT_PHASE=bootstrap; CORE_CHANGE_COMPLETE=true; ROLLBACK_STATUS=not_applicable_read_only_continuation; FAILURE_HANDLED=false
STEP_REPORT_URL=not_published; LATEST_ARCHIVE=not_created; LATEST_ARCHIVE_SHA256=unknown
mkdir -p "$EVIDENCE" "$REPORT" "$PAYLOAD"; chmod 700 "$EVIDENCE" "$REPORT" "$PAYLOAD"
source "$BASE/lib/router-step-workflow.sh"
router_step_workflow_init "$CURRENT" "$EVENTS" preflight independent_extract mandatory_tests live_postchange_verify source_publication model_publication methods_publication project_source report_build report_publish archive

vm101_script() {
  if [[ "$SELFTEST" == true ]]; then
    local body; body="$(cat)"
    if [[ "$body" == *'router-vm101-git-publish.sh --check'* ]]; then
      printf '%s\n' 'RESULT=PASS_vm101_GIT_PUBLISH_CHECK' "GIT_COMMIT=$VM101_GIT_COMMIT" "GIT_TREE=$VM101_GIT_TREE" "GIT_FILE_COUNT=$VM101_GIT_FILE_COUNT"
    elif [[ "$body" == *'sha256sum -c -'* ]]; then
      awk '{print $2 ": OK"}' "$BUNDLE_ROOT/reference/installed-files.sha256"
      echo RESULT=PASS_R20QUB1_R05_INSTALLED_FILE_HASHES
    elif [[ "$body" == *'router-egress-boot-handoff.sh --status'* ]]; then
      printf '%s\n' 'ready_present=false' 'RESULT=PASS_R20QUB1_R05_SERVICE_OWNERSHIP'
    elif [[ "$body" == *'router-egress-slots-status.sh'* ]]; then
      echo '{"healthy": 5, "mode": "NORMAL"}'
    else
      echo RESULT=STOP_R20QUB1_R05_SELFTEST_UNKNOWN_VM101_SCRIPT >&2; return 90
    fi
  else
    ssh -o BatchMode=yes -o ConnectTimeout=20 "$PVE_HOST" "ssh -i '$PVE_KEY' -o BatchMode=yes -o ConnectTimeout=20 root@'$VM101_ADDR' 'sh -s'"
  fi
}
pve_script() {
  if [[ "$SELFTEST" == true ]]; then cat >/dev/null; echo RESULT=PASS_R20QUB1_R05_EXISTING_SNAPSHOT_PRESENT
  else ssh -o BatchMode=yes -o ConnectTimeout=20 "$PVE_HOST" 'bash -s'; fi
}
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=true; 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; }
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" --run-dir "$RUN_DIR" --output "$REPORT" || true
 cp "$source_root/scripts/run-step.sh" "$REPORT/executed-step.sh" 2>/dev/null || true; cp "$source_root/release-info.json" "$REPORT/release-info.json" 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 mkdir -p "${ROUTER_PUBLIC_ROOT:?}/latest/r20qub1-r05-stop"; cp "$REPORT/report.txt" "$ROUTER_PUBLIC_ROOT/latest/r20qub1-r05-stop/report.txt"; STEP_REPORT_URL=selftest://r20qub1-r05-stop/; return 0; fi
 set +e; router_step_publish_payload step050m07r20qub1_r05_vm101_boot_handoff_publication_continuation_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/release-info.json" release-info.json "$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; publish_stop "$phase" "$line" "$rc" "$command" || true; archive_latest || true; write_child STOP_R20QUB1_R05_PUBLICATION_CONTINUATION "$rc"; echo RESULT=STOP_R20QUB1_R05_PUBLICATION_CONTINUATION; echo "STOP_PHASE=$phase"; echo "STOP_LINE=$line"; echo "STOP_RC=$rc"; printf 'STOP_COMMAND=%q\n' "$command"; echo CORE_CHANGE_COMPLETE=true; echo CORE_CHANGE_REPEATED=false; 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" ]]
printf 'BUNDLE_SHA256=%s\n' "$BUNDLE_SHA256" > "$RUN_DIR/bundle.env"; chmod 600 "$RUN_DIR/bundle.env"
"$BASE/bin/router-release-contract" verify --root "$BUNDLE_ROOT" --step "$STEP_ID"
grep -Fqx RESULT=PASS_R20QUB1_VM101_BOOT_HANDOFF_INSTALLED_ISOLATED_PROOF "$BUNDLE_ROOT/reference/r03-evidence/apply.log"
grep -Fqx ROUTER_CORE_CHANGE_COMPLETE=true "$BUNDLE_ROOT/reference/r03-evidence/apply.log"
grep -Fqx RESULT=PASS_vm101_GIT_PUBLISH "$BUNDLE_ROOT/reference/r03-evidence/vm101-git-publish.log"
grep -Fqx "GIT_COMMIT=$VM101_GIT_COMMIT" "$BUNDLE_ROOT/reference/r03-evidence/vm101-git-publish.log"
grep -Fqx STOP_PHASE=independent_extract "$BUNDLE_ROOT/reference/r04-evidence/report.txt"
router_step_phase_complete preflight prior_core_complete_and_r04_packaging_stop_classified

CURRENT_PHASE=independent_extract; router_step_phase_begin independent_extract
rm -rf "$FINAL_EXTRACT"; mkdir -p "$FINAL_EXTRACT"
"$BASE/bin/router-zip-contract" verify --zip "$BUNDLE_ZIP" --root "$STEP_ID" --canonical | tee "$EVIDENCE/zip-verify.log"
"$BASE/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"
"$BASE/bin/router-release-contract" verify --root "$FINAL_ROOT" --step "$STEP_ID"
router_step_phase_complete independent_extract shared_contract_v2_verified

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 exact_final_worker_pass_and_stop_paths_proven

if [[ -f "$BASE/selftest-force-stop" ]]; then false; fi
CURRENT_PHASE=live_postchange_verify; router_step_phase_begin live_postchange_verify
vm101_script > "$EVIDENCE/vm101-git-check.log" <<'EOS'
/usr/local/sbin/router-vm101-git-publish.sh --check
EOS
grep -Fqx RESULT=PASS_vm101_GIT_PUBLISH_CHECK "$EVIDENCE/vm101-git-check.log"; grep -Fqx "GIT_COMMIT=$VM101_GIT_COMMIT" "$EVIDENCE/vm101-git-check.log"; grep -Fqx "GIT_TREE=$VM101_GIT_TREE" "$EVIDENCE/vm101-git-check.log"; grep -Fqx "GIT_FILE_COUNT=$VM101_GIT_FILE_COUNT" "$EVIDENCE/vm101-git-check.log"
{ cat <<'EOS'
set -eu
cd /
sha256sum -c - <<'EOF_HASHES'
EOS
cat "$FINAL_ROOT/reference/installed-files.sha256"; cat <<'EOS'
EOF_HASHES
echo RESULT=PASS_R20QUB1_R05_INSTALLED_FILE_HASHES
EOS
} | vm101_script > "$EVIDENCE/vm101-installed-files.log"
grep -Fqx RESULT=PASS_R20QUB1_R05_INSTALLED_FILE_HASHES "$EVIDENCE/vm101-installed-files.log"
vm101_script > "$EVIDENCE/vm101-service-state.log" <<'EOS'
set -eu
/etc/init.d/router-egress-boot-handoff enabled
for service in router-egress-provider-direct router-wgpay-topology-delivery router-egress-zero-healthy-bootstrap router-egress-slots router-egress-health-repair router-egress-full-pool-refresh-retry; do if /etc/init.d/"$service" enabled >/dev/null 2>&1; then echo "UNEXPECTED_ENABLED_SERVICE=$service"; exit 41; fi; done
grep -Fqx PROVIDER_DIRECT_ENABLED=0 /etc/router-egress-provider-direct.conf
grep -Fqx BOOTSTRAP_CONTROLLER_PROVIDER_DIRECT_ENABLED=0 /etc/router-egress-zero-healthy-bootstrap.conf
if ps w 2>/dev/null | grep -F '/usr/local/sbin/router-egress-provider-direct.sh --loop' | grep -v grep >/dev/null 2>&1; then exit 42; fi
/usr/local/sbin/router-egress-boot-handoff.sh --status > /tmp/r20qub1-r05-boot-status.$$
if grep -Fqx ready_present=true /tmp/r20qub1-r05-boot-status.$$; then cat /tmp/r20qub1-r05-boot-status.$$; rm -f /tmp/r20qub1-r05-boot-status.$$; exit 43; fi
cat /tmp/r20qub1-r05-boot-status.$$; rm -f /tmp/r20qub1-r05-boot-status.$$
echo RESULT=PASS_R20QUB1_R05_SERVICE_OWNERSHIP
EOS
grep -Fqx RESULT=PASS_R20QUB1_R05_SERVICE_OWNERSHIP "$EVIDENCE/vm101-service-state.log"
vm101_script > "$EVIDENCE/vm101-live-slots.json" <<'EOS'
/usr/local/sbin/router-egress-slots-status.sh
EOS
grep -Eq '"healthy"[[:space:]]*:[[:space:]]*5' "$EVIDENCE/vm101-live-slots.json"
pve_script > "$EVIDENCE/snapshot-presence.log" <<EOF
set -Eeuo pipefail
qm listsnapshot 101 | awk '{print \$2}' | grep -Fxq '$SNAPSHOT_NAME'
echo RESULT=PASS_R20QUB1_R05_EXISTING_SNAPSHOT_PRESENT
EOF
grep -Fqx RESULT=PASS_R20QUB1_R05_EXISTING_SNAPSHOT_PRESENT "$EVIDENCE/snapshot-presence.log"
printf 'VM101_GIT_COMMIT=%s\nVM101_GIT_TREE=%s\nVM101_GIT_FILE_COUNT=%s\n' "$VM101_GIT_COMMIT" "$VM101_GIT_TREE" "$VM101_GIT_FILE_COUNT" > "$GIT_ENV"; chmod 600 "$GIT_ENV"
router_step_phase_complete live_postchange_verify exact_commit_files_services_snapshot_and_five_healthy_verified

CURRENT_PHASE=source_publication; router_step_phase_begin source_publication
"$BASE/bin/router-machine-close-safe" vm101 'STEP_050M07R20QUB1_R05: publish existing committed boot handoff source after workflow-v2 correction' | tee "$EVIDENCE/vm101-source-publication.log"
VM101_PUBLIC_URL="$(awk -F= '$1=="VM101_PUBLIC_URL"{print substr($0,index($0,"=")+1)}' "$EVIDENCE/vm101-source-publication.log"|tail -n1)"; [[ -n "$VM101_PUBLIC_URL" ]]
grep -Fqx "COMMIT=$VM101_GIT_COMMIT" "$EVIDENCE/vm101-source-publication.log"; grep -Fqx "TREE=$VM101_GIT_TREE" "$EVIDENCE/vm101-source-publication.log"; grep -Fqx "GIT_FILE_COUNT=$VM101_GIT_FILE_COUNT" "$EVIDENCE/vm101-source-publication.log"
printf 'VM101_PUBLIC_URL=%s\nVM101_GIT_COMMIT=%s\nVM101_GIT_TREE=%s\nVM101_GIT_FILE_COUNT=%s\n' "$VM101_PUBLIC_URL" "$VM101_GIT_COMMIT" "$VM101_GIT_TREE" "$VM101_GIT_FILE_COUNT" > "$SOURCE_ENV"; chmod 600 "$SOURCE_ENV"
router_step_phase_complete source_publication fresh_58_file_vm101_source_published

CURRENT_PHASE=model_publication; router_step_phase_begin model_publication
"$FINAL_ROOT/scripts/publish-vm101-model.sh" "$RUN_DIR" "$GIT_ENV" "$MODEL_ENV" | tee "$EVIDENCE/model-publication.log"
router_step_phase_complete model_publication fresh_vm101_model_published
CURRENT_PHASE=methods_publication; router_step_phase_begin methods_publication
"$FINAL_ROOT/scripts/publish-vm101-methods.sh" "$RUN_DIR" "$FINAL_ROOT" "$GIT_ENV" "$METHODS_ENV" | tee "$EVIDENCE/methods-publication.log"
router_step_phase_complete methods_publication fresh_vm101_methods_published
CURRENT_PHASE=project_source; router_step_phase_begin project_source
"$FINAL_ROOT/scripts/publish-project-source.sh" "$RUN_DIR" "$FINAL_ROOT" "$SOURCE_ENV" "$MODEL_ENV" "$METHODS_ENV" "$PROJECT_ENV" | tee "$EVIDENCE/project-source.log"
router_step_phase_complete project_source checkpoint_and_implementation_sources_published
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")" "$GIT_ENV" "$SOURCE_ENV" "$MODEL_ENV" "$METHODS_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 "$FINAL_ROOT/manifest.sha256" "$REPORT/bundle-manifest.sha256"; cp "$CURRENT" "$REPORT/workflow-current.txt"; cp "$EVENTS" "$REPORT/workflow-events.tsv"; cp "$EVIDENCE/"*.log "$REPORT/" 2>/dev/null || true; cp "$EVIDENCE/vm101-live-slots.json" "$REPORT/"
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 "${ROUTER_PUBLIC_ROOT:?}/latest/r20qub1-r05-pass"; cp "$REPORT/report.txt" "$ROUTER_PUBLIC_ROOT/latest/r20qub1-r05-pass/report.txt"; STEP_REPORT_URL=selftest://r20qub1-r05-pass/
else router_step_publish_payload step050m07r20qub1_r05_vm101_boot_handoff_publication_continuation "$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/bundle-manifest.sha256" bundle-manifest.sha256 "$REPORT/workflow-current.txt" workflow-current.txt "$REPORT/workflow-events.tsv" workflow-events.tsv "$REPORT/vm101-git-check.log" vm101-git-check.log "$REPORT/vm101-live-slots.json" vm101-live-slots.json "$REPORT/vm101-installed-files.log" vm101-installed-files.log "$REPORT/vm101-service-state.log" vm101-service-state.log "$REPORT/snapshot-presence.log" snapshot-presence.log "$REPORT/r03-apply.log" r03-apply.log "$REPORT/r03-isolated-proof.log" r03-isolated-proof.log "$REPORT/r03-vm101-git-publish.log" r03-vm101-git-publish.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_R20QUB1_VM101_BOOT_HANDOFF_ISOLATED_PROOF 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
