#!/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_050M07R20QT_VM100_SELECTOR_EMPTY_MOVE_HARDENING'
TARGET_PACKAGE_SHA='2f2a2e45560c10898d55801010ca38590f21bfe3d0d6934afcbb850ad0688b38'
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
VM100_BACKUP_DIR=''

archive_latest(){ "$BUNDLE_ROOT/scripts/archive-latest.sh"; }
source "$WORKFLOW_LIB"
rollback_now(){
  [ "$BACKUP_READY" = true ] || return 0
  [ "$CORE_CHANGE_COMPLETE" = false ] || return 0
  export VM100_BACKUP_DIR
  "$BUNDLE_ROOT/rollback/rollback.sh"
}
publish_stop_report(){
  local phase="$1" line="$2" 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"
  local 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
  )
  local f
  for f in preflight-main.txt preflight.txt vm100-source-check.txt vm101-source-check.txt pve-preflight.txt vm100-preflight.txt vm101-preflight.txt snapshot.txt backup.txt apply.txt postcheck.txt source-publish.txt project-source.txt rollback.txt; do
    [[ ! -f "$EVIDENCE_DIR/$f" ]] || {
      cp "$EVIDENCE_DIR/$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 step050m07r20qt_vm100_selector_empty_move_hardening \
    --payload-dir "$PUBLIC_PAYLOAD" --workflow-current "$CURRENT_FILE" \
    --workflow-events "$EVENTS_FILE" --output-env "$FINAL_ENV" --expect-kind step-report
}
stop(){
  local line="$1" rc="$2"
  trap - ERR
  set +e
  local guard="$RUN_DIR/.stop-handler-running"
  mkdir -p "$RUN_DIR" "$EVIDENCE_DIR" "$REPORT_DIR" "$PUBLIC_PAYLOAD" >/dev/null 2>&1 || true
  mkdir "$guard" 2>/dev/null || exit "$rc"
  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
  archive_latest
  [[ ! -f "$FINAL_ENV" ]] || cat "$FINAL_ENV"
  echo RESULT=STOP_R20QT_VM100_SELECTOR_EMPTY_MOVE_HARDENING
  echo STOP_PHASE="$phase"
  echo STOP_LINE="$line"
  echo STOP_RC="$rc"
  echo CORE_CHANGE_COMPLETE="$CORE_CHANGE_COMPLETE"
  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 postcheck source_publish 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_R20QT_PREFLIGHT "$EVIDENCE_DIR/preflight-main.txt"
cp "$EVIDENCE_DIR/preflight-main.txt" "$EVIDENCE_DIR/preflight.txt"
router_step_phase_complete preflight exact_machine_git_normal_runtime_and_target_busybox_syntax_verified

CURRENT_PHASE=snapshot
router_step_phase_begin snapshot
"$BUNDLE_ROOT/scripts/snapshot.sh" | tee "$EVIDENCE_DIR/snapshot.txt"
grep -Fqx RESULT=PASS_R20QT_SNAPSHOT "$EVIDENCE_DIR/snapshot.txt"
router_step_phase_complete snapshot vm100_prechange_snapshot_ready

CURRENT_PHASE=backup
router_step_phase_begin backup
"$BUNDLE_ROOT/scripts/backup-run.sh" "$RUN_ID" | tee "$EVIDENCE_DIR/backup.txt"
grep -Fqx RESULT=PASS_R20QT_BACKUP "$EVIDENCE_DIR/backup.txt"
VM100_BACKUP_DIR="$(awk -F= '$1=="VM100_BACKUP_DIR"{print substr($0,index($0,"=")+1)}' "$EVIDENCE_DIR/backup.txt" | tail -1)"
[[ -n "$VM100_BACKUP_DIR" ]]
BACKUP_READY=true
router_step_phase_complete backup exact_vm100_source_and_runtime_state_backed_up

CURRENT_PHASE=apply
router_step_phase_begin apply
"$BUNDLE_ROOT/scripts/apply-runtime.sh" "$TARGET_PACKAGE_SHA" "$VM100_BACKUP_DIR" | tee "$EVIDENCE_DIR/apply.txt"
grep -Fqx RESULT=PASS_R20QT_APPLY "$EVIDENCE_DIR/apply.txt"
grep -Fqx RESULT=PASS_R20QT_VM100_SELECTOR_EMPTY_MOVE_ISOLATED_PROOF "$EVIDENCE_DIR/apply.txt"
router_step_phase_complete apply two_vm100_paths_installed_and_empty_move_isolated_proof_passed_without_live_route_change

CURRENT_PHASE=postcheck
router_step_phase_begin postcheck
"$BUNDLE_ROOT/scripts/postcheck-run.sh" "$VM100_BACKUP_DIR" | tee "$EVIDENCE_DIR/postcheck.txt"
grep -Fqx RESULT=PASS_R20QT_POSTCHECK "$EVIDENCE_DIR/postcheck.txt"
CORE_CHANGE_COMPLETE=true
router_step_phase_complete postcheck production_runtime_unchanged_and_exact_two_path_staged_diff_verified

CURRENT_PHASE=source_publish
router_step_phase_begin source_publish
"$BUNDLE_ROOT/scripts/source-publish.sh" | tee "$EVIDENCE_DIR/source-publish.txt"
grep -Fqx RESULT=PASS_R20QT_SOURCE_PUBLISH "$EVIDENCE_DIR/source-publish.txt"
router_step_phase_complete source_publish vm100_machine_git_committed_published_and_vm101_unchanged

CURRENT_PHASE=project_source
router_step_phase_begin project_source
"$BUNDLE_ROOT/scripts/publish-project-source.sh" "$EVIDENCE_DIR/source-publish.txt" "$RUN_DIR/project-source" | tee "$EVIDENCE_DIR/project-source.txt"
grep -Fqx RESULT=PASS_R20QT_PROJECT_SOURCE_PUBLISH "$EVIDENCE_DIR/project-source.txt"
router_step_phase_complete project_source empty_move_hardening_proof_and_live_test_prerequisite_published

CURRENT_PHASE=report_build
router_step_phase_begin report_build
python3 "$BUNDLE_ROOT/scripts/build_report.py" \
  --preflight "$EVIDENCE_DIR/preflight.txt" --snapshot "$EVIDENCE_DIR/snapshot.txt" \
  --backup "$EVIDENCE_DIR/backup.txt" --apply "$EVIDENCE_DIR/apply.txt" \
  --postcheck "$EVIDENCE_DIR/postcheck.txt" --source "$EVIDENCE_DIR/source-publish.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"
cp "$BUNDLE_ROOT/install.sh" "$REPORT_DIR/executed-step.sh"
for f in preflight snapshot backup apply postcheck source-publish project-source; do
  cp "$EVIDENCE_DIR/$f.txt" "$REPORT_DIR/$f.txt"
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
)
for f in preflight snapshot backup apply postcheck source-publish project-source; do
  args+=("$REPORT_DIR/$f.txt" "$f.txt")
done
ROUTER_PUBLICATION_POLICY_LIB="$POLICY_LIB" "$SAFE_PAYLOAD" "$PUBLIC_PAYLOAD" "${args[@]}"
"$FINALIZER" --label step050m07r20qt_vm100_selector_empty_move_hardening \
  --payload-dir "$PUBLIC_PAYLOAD" --workflow-current "$CURRENT_FILE" \
  --workflow-events "$EVENTS_FILE" --output-env "$FINAL_ENV" --expect-kind step-report
router_step_workflow_mark_complete || true
router_step_phase_complete report_build final_pass_report_published

trap - ERR
archive_latest
cat "$FINAL_ENV"
cat "$REPORT_DIR/report.txt"
echo BOOTSTRAP_INSTALLER_RC=0
