#!/usr/bin/env bash
set -Eeuo pipefail
umask 077

BASE="${ROUTER_OPS_BASE:-/opt/router-ops}"
ROOT="${BUNDLE_ROOT:?}"
RUN_DIR="${ROUTER_DETACHED_RUN_DIR:?}"
CHILD_RESULT="${ROUTER_DETACHED_CHILD_RESULT:?}"
INCOMING="${ROUTER_STEP_INCOMING:-/home/ops/incoming}"
SELFTEST="${ROUTER_EXACT_WORKER_SELFTEST:-false}"

STEP=STEP_050M07P26C2_R01_CONTROLLED_LIVE_EXTERNAL_WIREGUARD_PROOF
VM100_COMMIT=8c5d11b7e4b119757ea16b46775b26e0ac903d7c
VM100_TREE=f25aab0f1886647b52a11ccebe080894bd06542a
VM100_COUNT=34
VM101_COMMIT=94a1c5627bacf9212d3fb2af1a77507ec57ff74b
VM101_TREE=ee4dddf35e308096d6496a4ecc25268ebcb3058a
VM101_COUNT=59
VM121_COMMIT=9bbb2aeacd669698055121a0f4fbaf5aa67720db
VM121_TREE=f83f404ca097962b1d407ad5b3c32da96acd4ee4
VM121_COUNT=51
VM100_PUBLIC_URL=https://reports.secret-studio.ru/latest/20260816-094040_vm100_git_source_8c5d11b7e4b1/
VM101_PUBLIC_URL=https://reports.secret-studio.ru/latest/20260816-094047_vm101_git_source_94a1c5627bac/
VM121_PUBLIC_URL=https://reports.secret-studio.ru/latest/20260817-091131_vm121_git_source_9bbb2aeacd66/
LOCAL_PLAN_URL=https://reports.secret-studio.ru/latest/20260719-080444_local_architecture_plan_vm101_autonomous_hmn_recovery_r19/
GLOBAL_PLAN_URL=https://reports.secret-studio.ru/latest/20260802-105248_global_project_plan_wg_paid_after_r20qw/
ACCESS_MAP_URL=https://reports.secret-studio.ru/latest/20260812-153301_access_map_canonical_current/
P25_REPORT_URL=https://reports.secret-studio.ru/latest/20260817-071459_step050m07p25_r02_controlled_synthetic_wireguard_domain_v2_e2e/
P26_REPORT_URL=https://reports.secret-studio.ru/latest/20260817-082619_step050m07p26_r03_invite_magic_link_secure_session_mvp/
P26C1_REPORT_URL=https://reports.secret-studio.ru/latest/20260817-091137_step050m07p26c1_r03_wireguard_config_qr_revoke_reissue_surface/

CURRENT="$RUN_DIR/workflow-current.txt"
EVENTS="$RUN_DIR/workflow-events.tsv"
EVIDENCE="$RUN_DIR/evidence"
REPORT="$RUN_DIR/report"
PAYLOAD="$RUN_DIR/public-payload"
FINAL_ENV="$RUN_DIR/final-publication.env"
TARGET_DIR="$RUN_DIR/target"
mkdir -p "$EVIDENCE" "$REPORT" "$PAYLOAD" "$TARGET_DIR" "$INCOMING"
chmod 700 "$EVIDENCE" "$REPORT" "$PAYLOAD" "$TARGET_DIR"

source "$BASE/lib/router-step-workflow.sh"
source <("$BASE/bin/router-release-contract" env --root "$ROOT")
router_step_workflow_init "$CURRENT" "$EVENTS" preflight live_test machine_close postcheck report_publish archive

CORE_CHANGE_COMPLETE=false
CORE_CHANGE_REPEATED=false
SOURCE_CHANGED=false
LIVE_DATABASE_WRITTEN=false
DATABASE_SCHEMA_CHANGED=false
RUNTIME_PROVISIONING_ACTIVE=false
EXTERNAL_ONBOARDING_ACTIVE=false
SYNTHETIC_CLEANUP_STATUS=not_started
BACKUP_DIR=unknown
STOP_DETAIL=unknown
STOP_HANDLED=false
STEP_REPORT_URL=unknown
LATEST_ARCHIVE=not_created
LATEST_ARCHIVE_SHA256=unknown
REMOTE_STAGE=unknown
REMOTE_PKG=unknown
XS_MAP_URL=unknown

last_field() {
  local key="$1"
  local file="$2"
  awk -F= -v k="$key" '$1==k{v=substr($0,index($0,"=")+1)} END{print v}' "$file"
}

write_child() {
  local result="$1"
  local rc="$2"
  local tmp="${CHILD_RESULT}.tmp.$$"
  {
    echo "RESULT=$result"
    echo "WORKER_RC=$rc"
    echo "CORE_CHANGE_COMPLETE=$CORE_CHANGE_COMPLETE"
    echo "CORE_CHANGE_REPEATED=$CORE_CHANGE_REPEATED"
    echo "SOURCE_CHANGED=$SOURCE_CHANGED"
    echo "LIVE_DATABASE_WRITTEN=$LIVE_DATABASE_WRITTEN"
    echo "DATABASE_SCHEMA_CHANGED=$DATABASE_SCHEMA_CHANGED"
    echo "RUNTIME_PROVISIONING_ACTIVE=false"
    echo "EXTERNAL_ONBOARDING_ACTIVE=false"
    echo "SYNTHETIC_CLEANUP_STATUS=$SYNTHETIC_CLEANUP_STATUS"
    echo "BACKUP_DIR=$BACKUP_DIR"
    echo "VM100_COMMIT=$VM100_COMMIT"
    echo "VM100_TREE=$VM100_TREE"
    echo "VM100_FILE_COUNT=$VM100_COUNT"
    echo "VM100_PUBLIC_URL=$VM100_PUBLIC_URL"
    echo "VM101_COMMIT=$VM101_COMMIT"
    echo "VM101_TREE=$VM101_TREE"
    echo "VM101_FILE_COUNT=$VM101_COUNT"
    echo "VM101_PUBLIC_URL=$VM101_PUBLIC_URL"
    echo "VM121_COMMIT=$VM121_COMMIT"
    echo "VM121_TREE=$VM121_TREE"
    echo "VM121_FILE_COUNT=$VM121_COUNT"
    echo "VM121_PUBLIC_URL=$VM121_PUBLIC_URL"
    echo "STEP_REPORT_URL=$STEP_REPORT_URL"
    echo "LATEST_ARCHIVE=$LATEST_ARCHIVE"
    echo "LATEST_ARCHIVE_SHA256=$LATEST_ARCHIVE_SHA256"
  } > "$tmp"
  chmod 600 "$tmp"
  mv "$tmp" "$CHILD_RESULT"
}

archive_latest() {
  local log="$EVIDENCE/archive.log"
  router_step_archive_latest_python "$BASE" "$INCOMING" "$(date -u +%Y%m%d-%H%M%S)" | tee "$log"
  LATEST_ARCHIVE="$(last_field LATEST_ARCHIVE "$log")"
  LATEST_ARCHIVE_SHA256="$(last_field LATEST_ARCHIVE_SHA256 "$log")"
}

cleanup_remote() {
  [[ "$SELFTEST" == false ]] || return 0
  [[ "$REMOTE_STAGE" != unknown ]] || return 0
  set +e
  ssh -T -o BatchMode=yes -o ConnectTimeout=20 vm121 "rm -rf '$REMOTE_STAGE' '$REMOTE_PKG'" >/dev/null 2>&1
  set -e
}

resolve_xs_map() {
  local f=/opt/router-ops/inventory/XS_MAP_CURRENT.md
  local u=''
  if [[ -r "$f" ]]; then
    u="$(grep -Eo 'https://reports\.secret-studio\.ru/[^[:space:]`)]+' "$f" 2>/dev/null | tail -n1 || true)"
  fi
  [[ -n "$u" ]] && XS_MAP_URL="$u" || XS_MAP_URL=unknown
}

write_stop_report() {
  local rc="$1"
  local line="$2"
  local command="$3"
  cat > "$REPORT/report.txt" <<EOF
RESULT=STOP_P26C2_CONTROLLED_LIVE_EXTERNAL_WIREGUARD_PROOF
REVISION=R01
STOP_RC=$rc
STOP_LINE=$line
STOP_DETAIL=$STOP_DETAIL
CORE_CHANGE_COMPLETE=$CORE_CHANGE_COMPLETE
CORE_CHANGE_REPEATED=false
SOURCE_CHANGED=false
LIVE_DATABASE_WRITTEN=$LIVE_DATABASE_WRITTEN
DATABASE_SCHEMA_CHANGED=false
SYNTHETIC_CLEANUP_STATUS=$SYNTHETIC_CLEANUP_STATUS
BACKUP_DIR=$BACKUP_DIR
RUNTIME_PROVISIONING_ACTIVE=false
EXTERNAL_ONBOARDING_ACTIVE=false
VM100_COMMIT=$VM100_COMMIT
VM100_TREE=$VM100_TREE
VM100_PUBLIC_URL=$VM100_PUBLIC_URL
VM101_COMMIT=$VM101_COMMIT
VM101_TREE=$VM101_TREE
VM101_PUBLIC_URL=$VM101_PUBLIC_URL
VM121_COMMIT=$VM121_COMMIT
VM121_TREE=$VM121_TREE
VM121_PUBLIC_URL=$VM121_PUBLIC_URL
LOCAL_PLAN_URL=$LOCAL_PLAN_URL
GLOBAL_PLAN_URL=$GLOBAL_PLAN_URL
ACCESS_MAP_URL=$ACCESS_MAP_URL
XS_MAP_URL=$XS_MAP_URL
NEXT_ACTION=inspect retained evidence; if CORE_CHANGE_COMPLETE=true do not replay live P26C2 core, continue publication/postcheck only
EOF
  printf 'STOP_COMMAND=%q\n' "$command" >> "$REPORT/report.txt"
  cp "$REPORT/report.txt" "$REPORT/verify.txt"
  cp "$ROOT/scripts/run-step.sh" "$REPORT/executed-step.sh"
  cp "$ROOT/release-info.json" "$REPORT/release-info.json"
  cp "$ROOT/rollback/README.md" "$REPORT/rollback.txt"
  for f in \
    pre-vm100-source.txt pre-vm101-source.txt pre-vm121-source.txt \
    pre-vm100-source-validation.txt pre-vm101-source-validation.txt pre-vm121-source-validation.txt \
    pre-vm121-live.txt pre-vm100-live.txt pre-vm101-live.txt live-test.txt \
    post-vm100-source.txt post-vm101-source.txt post-vm121-source.txt \
    post-vm100-source-validation.txt post-vm101-source-validation.txt post-vm121-source-validation.txt \
    post-vm121-live.txt post-vm100-live.txt post-vm101-live.txt; do
    [[ ! -f "$EVIDENCE/$f" ]] || cp "$EVIDENCE/$f" "$REPORT/$f"
  done
}

stop_handler() {
  local rc="$1"
  local line="$2"
  local command="$3"
  trap - ERR
  [[ "$STOP_HANDLED" == false ]] || return "$rc"
  STOP_HANDLED=true
  cleanup_remote
  resolve_xs_map
  write_stop_report "$rc" "$line" "$command"
  set +e
  if [[ "$SELFTEST" == false ]]; then
    local args=()
    while IFS= read -r f; do
      args+=("$f" "$(basename "$f")")
    done < <(find "$REPORT" -maxdepth 1 -type f -print | LC_ALL=C sort)
    router_step_publish_payload step050m07p26c2_r01_controlled_live_external_wireguard_proof_stop \
      "$REPORT" "$PAYLOAD" "$CURRENT" "$EVENTS" "$FINAL_ENV" "${args[@]}" >/dev/null 2>&1 || true
    [[ -f "$FINAL_ENV" ]] && STEP_REPORT_URL="$(last_field PUBLIC_URL "$FINAL_ENV")"
    archive_latest >/dev/null 2>&1 || true
  fi
  set -e
  write_child STOP_P26C2_CONTROLLED_LIVE_EXTERNAL_WIREGUARD_PROOF "$rc"
  return "$rc"
}
trap 'rc=$?; stop_handler "$rc" "$LINENO" "$BASH_COMMAND"; exit "$rc"' ERR

selftest_worker() {
  local pkg="$ROOT/$ROUTER_RELEASE_TARGET_PACKAGE_PATH"
  local sha
  sha="$(sha256sum "$pkg" | awk '{print $1}')"
  [[ "$sha" == "$ROUTER_RELEASE_TARGET_PACKAGE_SHA256" ]]
  tar -tzf "$pkg" | grep -Fq './vm121-p26c2-live.sh'
  tar -tzf "$pkg" | grep -Fq './p26c2_helper.py'
  mkdir -p "$TARGET_DIR/selftest"
  tar -xzf "$pkg" -C "$TARGET_DIR/selftest"
  bash -n "$TARGET_DIR/selftest/vm121-p26c2-live.sh"
  python3 - "$TARGET_DIR/selftest/p26c2_helper.py" <<'PY'
from pathlib import Path
import sys
p=Path(sys.argv[1])
compile(p.read_bytes(),str(p),'exec')
t=p.read_text(encoding='utf-8')
for required in ('bootstrap','create-profile','get-config','revoke','reissue','secret-scan','cleanup','final-counts'):
    assert required in t
print('SELFTEST_HELPER_ACTIONS=PASS')
PY
  for marker in \
    'FIRST_EXTERNAL_HANDSHAKE_AND_INTERNET=PASS' \
    'OLD_CONFIG_REVOKE_EFFECT=PASS' \
    'SECOND_EXTERNAL_HANDSHAKE_AND_INTERNET=PASS' \
    'REISSUE_CONFIG_CHANGED=true' \
    'SYNTHETIC_DB_FINAL_ZERO=true' \
    'SYNTHETIC_VM100_FINAL_ZERO=true' \
    'P26C2_ERROR_CLEANUP_STATUS='; do
    grep -Fq "$marker" "$TARGET_DIR/selftest/vm121-p26c2-live.sh"
  done
  grep -Fq 'EXTERNAL_ONBOARDING_ACTIVE=true' "$TARGET_DIR/selftest/vm121-p26c2-live.sh"
  grep -Fq -- '--host 127.0.0.1 --port 18082' "$TARGET_DIR/selftest/vm121-p26c2-live.sh"
  grep -Fq "grep -Fxq '0.0.0.0/0'" "$TARGET_DIR/selftest/vm121-p26c2-live.sh"
  echo TEMP_AUTH_API_LOCALHOST_CONTRACT=PASS
  echo EXTERNAL_CLIENT_DEFAULT_ROUTE_CONTRACT=PASS
  echo REVOKE_REISSUE_HANDSHAKE_CONTRACT=PASS
  echo RESULT=PASS_P26C2_R01_EXACT_WORKER_SELFTEST
  write_child PASS_P26C2_R01_EXACT_WORKER_SELFTEST 0
}

if [[ "$SELFTEST" == true ]]; then
  selftest_worker
  trap - ERR
  exit 0
fi

collect_vm121_live() {
  local outfile="$1"
  ssh -T -o BatchMode=yes -o ConnectTimeout=20 vm121 /bin/bash -s > "$outfile" 2>&1 <<'VM121'
set -Eeuo pipefail
curl -fsS --max-time 5 http://127.0.0.1:18080/health >/dev/null
curl -fsS --max-time 5 http://127.0.0.1:18080/health/db >/dev/null
PG=wgaccess-postgres
U="$(docker exec "$PG" sh -lc 'printf %s "$POSTGRES_USER"')"
D="$(docker exec "$PG" sh -lc 'printf %s "$POSTGRES_DB"')"
Q(){ docker exec "$PG" psql -v ON_ERROR_STOP=1 -U "$U" -d "$D" -Atqc "$1"; }
ALEMBIC_VERSION="$(Q 'SELECT version_num FROM alembic_version')"
BUSINESS_ROWS="$(Q "SELECT (SELECT count(*) FROM users)+(SELECT count(*) FROM plans)+(SELECT count(*) FROM access_grants)+(SELECT count(*) FROM access_grant_protocol_limits)+(SELECT count(*) FROM invites)+(SELECT count(*) FROM invite_redemptions)+(SELECT count(*) FROM magic_link_tokens)+(SELECT count(*) FROM auth_sessions)+(SELECT count(*) FROM connection_profiles)+(SELECT count(*) FROM peer_credentials)+(SELECT count(*) FROM audit_events)+(SELECT count(*) FROM invite_codes)+(SELECT count(*) FROM orders)+(SELECT count(*) FROM subscriptions)+(SELECT count(*) FROM peers)+(SELECT count(*) FROM provisioning_jobs)+(SELECT count(*) FROM peer_egress_leases)")"
PROFILE_ROWS="$(Q 'SELECT count(*) FROM connection_profiles')"
CRED_ROWS="$(Q 'SELECT count(*) FROM peer_credentials')"
JOB_ROWS="$(Q 'SELECT count(*) FROM provisioning_jobs')"
K=/opt/wg-access/runtime/credential-keyring.json
[[ -f "$K" ]]
OWNER="$(stat -c '%U:%G' "$K")"
MODE="$(stat -c '%a' "$K")"
AP="$(systemctl is-active wg-access-agent.path 2>/dev/null || true)"
EP="$(systemctl is-enabled wg-access-agent.path 2>/dev/null || true)"
AT="$(systemctl is-active wg-access-agent.timer 2>/dev/null || true)"
ET="$(systemctl is-enabled wg-access-agent.timer 2>/dev/null || true)"
AS="$(systemctl is-active wg-access-agent.service 2>/dev/null || true)"
echo BACKEND_HEALTH=PASS
echo "ALEMBIC_VERSION=$ALEMBIC_VERSION"
echo "BUSINESS_ROWS=$BUSINESS_ROWS"
echo "CONNECTION_PROFILE_ROWS=$PROFILE_ROWS"
echo "PEER_CREDENTIAL_ROWS=$CRED_ROWS"
echo "PROVISIONING_JOB_ROWS=$JOB_ROWS"
echo "KEYRING_OWNER=$OWNER"
echo "KEYRING_MODE=$MODE"
echo "AGENT_PATH_ACTIVE=$AP"
echo "AGENT_PATH_ENABLED=$EP"
echo "AGENT_TIMER_ACTIVE=$AT"
echo "AGENT_TIMER_ENABLED=$ET"
echo "AGENT_SERVICE_ACTIVE=$AS"
echo "AGENT_SOURCE_MODE=$(stat -c '%a' /opt/wg-access/agent/wg_access_agent.py)"
EO="$(docker exec wgaccess-backend python -c 'from app.config import settings; print(str(settings.external_onboarding_active).lower())')"
echo "EXTERNAL_ONBOARDING_ACTIVE=$EO"
[[ "$ALEMBIC_VERSION" == 0004_profile_provisioning ]]
[[ "$BUSINESS_ROWS" == 0 && "$PROFILE_ROWS" == 0 && "$CRED_ROWS" == 0 && "$JOB_ROWS" == 0 ]]
[[ "$OWNER" == root:root && "$MODE" == 600 ]]
[[ "$AP" == inactive && "$EP" == disabled && "$AT" == inactive && "$ET" == disabled && "$AS" == inactive ]]
[[ "$EO" == false ]]
[[ "$(stat -c '%a' /opt/wg-access/agent/wg_access_agent.py)" == 755 ]]
echo RESULT=PASS_P26C2_VM121_LIVE_ZERO_BASELINE
VM121
}

collect_vm100_live() {
  local outfile="$1"
  ssh -T -o BatchMode=yes -o ConnectTimeout=20 pve-mgts \
    "ssh -T -o BatchMode=yes -o ConnectTimeout=10 -i /root/.ssh/pve_to_openwrt_mgts_ed25519 root@10.71.100.1 /bin/sh -s" > "$outfile" 2>&1 <<'VM100'
set -eu
L=/usr/local/sbin/router-wgpay-peer-lifecycle.sh
C=/etc/router-wgpay-peer-lifecycle.conf
B=/etc/nftables.d/92-beach-omr-routing.nft
[ -x "$L" ]
[ -r "$C" ]
[ -f "$B" ]
"$L" --status
. "$C"
REGISTRY_ROWS="$(awk -F '\t' '$0!~/^#/ && NF{n++} END{print n+0}' "$PEER_REGISTRY_FILE")"
RUNTIME_ROWS="$("$PEER_WIREGUARD_CLI" show "$PEER_WIREGUARD_INTERFACE" peers 2>/dev/null | awk 'NF{n++} END{print n+0}')"
echo "VM100_REGISTRY_ROWS=$REGISTRY_ROWS"
LISTEN_PORT="$("$PEER_WIREGUARD_CLI" show "$PEER_WIREGUARD_INTERFACE" listen-port 2>/dev/null || true)"
echo "VM100_WG_PAID_RUNTIME_PEERS=$RUNTIME_ROWS"
echo "VM100_WG_PAID_LISTEN_PORT=$LISTEN_PORT"
echo BEACH_VM100_FILE_PRESENT=true
echo "BEACH_VM100_FILE_SHA256=$(sha256sum "$B" | awk '{print $1}')"
[ "$REGISTRY_ROWS" -eq 0 ]
[ "$RUNTIME_ROWS" -eq 0 ]
[ "$LISTEN_PORT" = 51830 ]
echo RESULT=PASS_P26C2_VM100_LIVE_ZERO_BASELINE
VM100
}

collect_vm101_live() {
  local outfile="$1"
  ssh -T -o BatchMode=yes -o ConnectTimeout=20 pve-mgts \
    "ssh -T -o BatchMode=yes -o ConnectTimeout=10 -i /root/.ssh/pve_to_openwrt_mgts_ed25519 root@10.71.100.2 /bin/sh -s" > "$outfile" 2>&1 <<'VM101'
set -eu
F=/etc/config/firewall
[ -f "$F" ]
for port in 65248 65301 65500; do grep -Fq "$port" "$F"; done
grep -Fq '10.71.100.85' "$F"
grep -Fq "config redirect 'dnat_wg_paid_51830'" "$F"
grep -Fq "option src_dport '51830'" "$F"
grep -Fq "option dest_ip '10.71.100.1'" "$F"
grep -Fq "option dest_port '51830'" "$F"
grep -Fq "option proto 'udp'" "$F"
echo WG_PAID_PUBLIC_DNAT_51830_PRESENT=true
echo BEACH_VM101_FIREWALL_FILE_PRESENT=true
echo BEACH_VM101_DNAT_PORTS_PRESENT=true
echo BEACH_VM101_VM102_TARGET_PRESENT=true
echo "BEACH_VM101_FIREWALL_SHA256=$(sha256sum "$F" | awk '{print $1}')"
echo RESULT=PASS_P26C2_VM101_BEACH_BASELINE
VM101
}

router_step_phase_begin preflight
ssh -T -o BatchMode=yes -o ConnectTimeout=20 vm121 /usr/local/sbin/router-vm121-git-publish.sh --check > "$EVIDENCE/pre-vm121-source.txt" 2>&1
ssh -T -o BatchMode=yes -o ConnectTimeout=20 pve-mgts \
  "ssh -n -o BatchMode=yes -o ConnectTimeout=10 -i /root/.ssh/pve_to_openwrt_mgts_ed25519 root@10.71.100.1 /usr/local/sbin/router-vm100-git-publish.sh --check" > "$EVIDENCE/pre-vm100-source.txt" 2>&1
ssh -T -o BatchMode=yes -o ConnectTimeout=20 pve-mgts \
  "ssh -n -o BatchMode=yes -o ConnectTimeout=10 -i /root/.ssh/pve_to_openwrt_mgts_ed25519 root@10.71.100.2 /usr/local/sbin/router-vm101-git-publish.sh --check" > "$EVIDENCE/pre-vm101-source.txt" 2>&1
"$ROOT/scripts/source-check-validate.sh" "$EVIDENCE/pre-vm100-source.txt" vm100 "$VM100_COMMIT" "$VM100_TREE" "$VM100_COUNT" > "$EVIDENCE/pre-vm100-source-validation.txt" || { STOP_DETAIL=pre_vm100_source; false; }
"$ROOT/scripts/source-check-validate.sh" "$EVIDENCE/pre-vm101-source.txt" vm101 "$VM101_COMMIT" "$VM101_TREE" "$VM101_COUNT" > "$EVIDENCE/pre-vm101-source-validation.txt" || { STOP_DETAIL=pre_vm101_source; false; }
"$ROOT/scripts/source-check-validate.sh" "$EVIDENCE/pre-vm121-source.txt" vm121 "$VM121_COMMIT" "$VM121_TREE" "$VM121_COUNT" > "$EVIDENCE/pre-vm121-source-validation.txt" || { STOP_DETAIL=pre_vm121_source; false; }
collect_vm121_live "$EVIDENCE/pre-vm121-live.txt" || { STOP_DETAIL=pre_vm121_live; false; }
collect_vm100_live "$EVIDENCE/pre-vm100-live.txt" || { STOP_DETAIL=pre_vm100_live; false; }
collect_vm101_live "$EVIDENCE/pre-vm101-live.txt" || { STOP_DETAIL=pre_vm101_beach; false; }
PRE_VM100_BEACH_SHA="$(last_field BEACH_VM100_FILE_SHA256 "$EVIDENCE/pre-vm100-live.txt")"
PRE_VM101_BEACH_SHA="$(last_field BEACH_VM101_FIREWALL_SHA256 "$EVIDENCE/pre-vm101-live.txt")"
PKG="$ROOT/$ROUTER_RELEASE_TARGET_PACKAGE_PATH"
ACTUAL_PKG_SHA="$(sha256sum "$PKG" | awk '{print $1}')"
[[ "$ACTUAL_PKG_SHA" == "$ROUTER_RELEASE_TARGET_PACKAGE_SHA256" ]] || { STOP_DETAIL=target_package_sha; false; }
tar -tzf "$PKG" > "$EVIDENCE/target-package-list.txt"
grep -Fq './vm121-p26c2-live.sh' "$EVIDENCE/target-package-list.txt"
grep -Fq './p26c2_helper.py' "$EVIDENCE/target-package-list.txt"
router_step_phase_complete preflight exact_sources_zero_state_backup_boundary_and_beach_verified

router_step_phase_begin live_test
LIVE_DATABASE_WRITTEN=false
token="$(basename "$RUN_DIR" | tr -cd 'A-Za-z0-9._-')"
REMOTE_STAGE="/root/router-step-p26c2-r01-$token"
REMOTE_PKG="/root/router-step-p26c2-r01-$token.tar.gz"
ssh -T -o BatchMode=yes -o ConnectTimeout=20 vm121 "umask 077; cat > '$REMOTE_PKG'" < "$PKG" || { STOP_DETAIL=remote_package_transfer; false; }
ssh -T -o BatchMode=yes -o ConnectTimeout=20 vm121 \
  "rm -rf '$REMOTE_STAGE'; install -d -m 0700 '$REMOTE_STAGE'; tar -xzf '$REMOTE_PKG' -C '$REMOTE_STAGE'" > "$EVIDENCE/remote-stage.txt" 2>&1 || { STOP_DETAIL=remote_package_extract; false; }
if ssh -T -o BatchMode=yes -o ConnectTimeout=20 vm121 \
  "/bin/bash '$REMOTE_STAGE/vm121-p26c2-live.sh' '$REMOTE_STAGE/p26c2_helper.py'" > "$EVIDENCE/live-test.txt" 2>&1; then
  LIVE_DATABASE_WRITTEN="$(last_field LIVE_DATABASE_MUTATION_STARTED "$EVIDENCE/live-test.txt")"
  [[ "$LIVE_DATABASE_WRITTEN" == true ]] || { STOP_DETAIL=live_database_mutation_marker_missing; false; }
else
  marker="$(last_field LIVE_DATABASE_MUTATION_STARTED "$EVIDENCE/live-test.txt")"
  [[ "$marker" == true ]] && LIVE_DATABASE_WRITTEN=true || LIVE_DATABASE_WRITTEN=false
  SYNTHETIC_CLEANUP_STATUS="$(last_field P26C2_ERROR_CLEANUP_STATUS "$EVIDENCE/live-test.txt")"
  [[ -n "$SYNTHETIC_CLEANUP_STATUS" ]] || SYNTHETIC_CLEANUP_STATUS=unknown
  BACKUP_DIR="$(last_field BACKUP_DIR "$EVIDENCE/live-test.txt")"
  [[ -n "$BACKUP_DIR" ]] || BACKUP_DIR=unknown
  STOP_DETAIL=live_test_failed
  false
fi
for kv in \
  'RESULT=PASS_P26C2_CONTROLLED_LIVE_EXTERNAL_WIREGUARD_PROOF' \
  'CORE_FIRST_EXTERNAL_HANDSHAKE_PROVEN=true' \
  'CORE_OLD_CONFIG_REVOKE_PROVEN=true' \
  'CORE_SECOND_EXTERNAL_HANDSHAKE_PROVEN=true' \
  'CORE_FINAL_REVOKE_PROVEN=true' \
  'AUTHENTICATED_CONFIG_SURFACE_LIVE=PASS' \
  'INTERNET_DATA_PLANE_FIRST=PASS' \
  'INTERNET_DATA_PLANE_SECOND=PASS' \
  'REISSUE_ROTATED_CONFIG_AND_PUBLIC_KEY=PASS' \
  'SYNTHETIC_DB_FINAL_ZERO=true' \
  'SYNTHETIC_VM100_FINAL_ZERO=true' \
  'SECRET_LEAKAGE_PROOF=PASS' \
  'ENCRYPTED_BACKUP_PRESENT=true' \
  'BACKUP_RESTORE_PROOF=PASS' \
  'RUNTIME_PROVISIONING_ACTIVE=false' \
  'EXTERNAL_ONBOARDING_ACTIVE=false'; do
  grep -Fqx "$kv" "$EVIDENCE/live-test.txt" || { STOP_DETAIL="live_semantics_${kv%%=*}"; false; }
done
VM100_SELECTED_SELECTOR_FIRST="$(last_field VM100_SELECTED_SELECTOR_FIRST "$EVIDENCE/live-test.txt")"
VM100_SELECTED_SELECTOR_SECOND="$(last_field VM100_SELECTED_SELECTOR_SECOND "$EVIDENCE/live-test.txt")"
case "$VM100_SELECTED_SELECTOR_FIRST" in cs1|cs2|cs3|cs4|cs5) ;; *) STOP_DETAIL=vm100_selector_first_invalid; false ;; esac
case "$VM100_SELECTED_SELECTOR_SECOND" in cs1|cs2|cs3|cs4|cs5) ;; *) STOP_DETAIL=vm100_selector_second_invalid; false ;; esac
BACKUP_DIR="$(last_field BACKUP_DIR "$EVIDENCE/live-test.txt")"
[[ -n "$BACKUP_DIR" ]] || { STOP_DETAIL=backup_dir_missing; false; }
SYNTHETIC_CLEANUP_STATUS=PASS
CORE_CHANGE_COMPLETE=true
cleanup_remote
router_step_phase_complete live_test authenticated_config_first_handshake_revoke_reissue_second_handshake_and_cleanup_proven

router_step_phase_begin machine_close
router_step_phase_skip machine_close source_unchanged_no_machine_close_required

router_step_phase_begin postcheck
ssh -T -o BatchMode=yes -o ConnectTimeout=20 vm121 /usr/local/sbin/router-vm121-git-publish.sh --check > "$EVIDENCE/post-vm121-source.txt" 2>&1
ssh -T -o BatchMode=yes -o ConnectTimeout=20 pve-mgts \
  "ssh -n -o BatchMode=yes -o ConnectTimeout=10 -i /root/.ssh/pve_to_openwrt_mgts_ed25519 root@10.71.100.1 /usr/local/sbin/router-vm100-git-publish.sh --check" > "$EVIDENCE/post-vm100-source.txt" 2>&1
ssh -T -o BatchMode=yes -o ConnectTimeout=20 pve-mgts \
  "ssh -n -o BatchMode=yes -o ConnectTimeout=10 -i /root/.ssh/pve_to_openwrt_mgts_ed25519 root@10.71.100.2 /usr/local/sbin/router-vm101-git-publish.sh --check" > "$EVIDENCE/post-vm101-source.txt" 2>&1
"$ROOT/scripts/source-check-validate.sh" "$EVIDENCE/post-vm100-source.txt" vm100 "$VM100_COMMIT" "$VM100_TREE" "$VM100_COUNT" > "$EVIDENCE/post-vm100-source-validation.txt" || { STOP_DETAIL=post_vm100_source; false; }
"$ROOT/scripts/source-check-validate.sh" "$EVIDENCE/post-vm101-source.txt" vm101 "$VM101_COMMIT" "$VM101_TREE" "$VM101_COUNT" > "$EVIDENCE/post-vm101-source-validation.txt" || { STOP_DETAIL=post_vm101_source; false; }
"$ROOT/scripts/source-check-validate.sh" "$EVIDENCE/post-vm121-source.txt" vm121 "$VM121_COMMIT" "$VM121_TREE" "$VM121_COUNT" > "$EVIDENCE/post-vm121-source-validation.txt" || { STOP_DETAIL=post_vm121_source; false; }
collect_vm121_live "$EVIDENCE/post-vm121-live.txt" || { STOP_DETAIL=post_vm121_live; false; }
collect_vm100_live "$EVIDENCE/post-vm100-live.txt" || { STOP_DETAIL=post_vm100_live; false; }
collect_vm101_live "$EVIDENCE/post-vm101-live.txt" || { STOP_DETAIL=post_vm101_beach; false; }
POST_VM100_BEACH_SHA="$(last_field BEACH_VM100_FILE_SHA256 "$EVIDENCE/post-vm100-live.txt")"
POST_VM101_BEACH_SHA="$(last_field BEACH_VM101_FIREWALL_SHA256 "$EVIDENCE/post-vm101-live.txt")"
[[ "$POST_VM100_BEACH_SHA" == "$PRE_VM100_BEACH_SHA" ]] || { STOP_DETAIL=beach_vm100_changed; false; }
[[ "$POST_VM101_BEACH_SHA" == "$PRE_VM101_BEACH_SHA" ]] || { STOP_DETAIL=beach_vm101_changed; false; }
router_step_phase_complete postcheck exact_source_zero_state_inactive_agent_and_beach_preserved

router_step_phase_begin report_publish
resolve_xs_map
cat > "$REPORT/report.txt" <<EOF
RESULT=PASS_P26C2_CONTROLLED_LIVE_EXTERNAL_WIREGUARD_PROOF
REVISION=R01
CORE_CHANGE_COMPLETE=true
CORE_CHANGE_REPEATED=false
SOURCE_CHANGED=false
LIVE_DATABASE_WRITTEN=true
DATABASE_SCHEMA_CHANGED=false
ALEMBIC_VERSION=0004_profile_provisioning
AUTHENTICATED_CONFIG_SURFACE_LIVE=PASS
TUNNEL_IP_RESERVED_BEFORE_VM100=PASS
JOB_PAYLOAD_SECRET_FIELDS_ABSENT=PASS
JOB_PAYLOAD_SELECTOR_FIELDS_ABSENT=PASS
VM100_SELECTOR_AUTHORITY=VM100
VM100_SELECTED_SELECTOR_FIRST=$VM100_SELECTED_SELECTOR_FIRST
VM100_SELECTED_SELECTOR_SECOND=$VM100_SELECTED_SELECTOR_SECOND
FIRST_EXTERNAL_WIREGUARD_HANDSHAKE=PASS
FIRST_SERVER_TUNNEL_PING=PASS
FIRST_INTERNET_DATA_PLANE=PASS
OLD_CONFIG_REVOKE_EFFECT=PASS
REISSUE_CONFIG_CHANGED=true
REISSUE_PUBLIC_KEY_CHANGED=true
SECOND_EXTERNAL_WIREGUARD_HANDSHAKE=PASS
SECOND_SERVER_TUNNEL_PING=PASS
SECOND_INTERNET_DATA_PLANE=PASS
FINAL_REVOKE_EFFECT=PASS
DYNAMIC_EVIDENCE_PRIVATE_KEYS_ABSENT=PASS
DYNAMIC_EVIDENCE_PSKS_ABSENT=PASS
SYNTHETIC_DB_FINAL_ZERO=true
SYNTHETIC_VM100_FINAL_ZERO=true
SYNTHETIC_CLEANUP_STATUS=PASS
ENCRYPTED_BACKUP_PRESENT=true
BACKUP_RESTORE_PROOF=PASS
BACKUP_DIR=$BACKUP_DIR
WG_PAID_PUBLIC_ENDPOINT_PORT=51830
BEACH_VM100_PRESERVED=true
BEACH_VM101_PRESERVED=true
VM101_WG_PAID_DNAT_PRESERVED=true
RUNTIME_PROVISIONING_ACTIVE=false
EXTERNAL_ONBOARDING_ACTIVE=false
PUBLIC_CONFIG_QR_ACTIVE=false
EXTERNAL_CLIENT_HANDSHAKE_PROVEN=true
SMTP_TLS_DELIVERY_ACTIVE=false
VM100_COMMIT=$VM100_COMMIT
VM100_TREE=$VM100_TREE
VM100_FILE_COUNT=$VM100_COUNT
VM100_PUBLIC_URL=$VM100_PUBLIC_URL
VM101_COMMIT=$VM101_COMMIT
VM101_TREE=$VM101_TREE
VM101_FILE_COUNT=$VM101_COUNT
VM101_PUBLIC_URL=$VM101_PUBLIC_URL
VM121_COMMIT=$VM121_COMMIT
VM121_TREE=$VM121_TREE
VM121_FILE_COUNT=$VM121_COUNT
VM121_PUBLIC_URL=$VM121_PUBLIC_URL
P25_REPORT_URL=$P25_REPORT_URL
P26_REPORT_URL=$P26_REPORT_URL
P26C1_REPORT_URL=$P26C1_REPORT_URL
LOCAL_PLAN_URL=$LOCAL_PLAN_URL
GLOBAL_PLAN_URL=$GLOBAL_PLAN_URL
ACCESS_MAP_URL=$ACCESS_MAP_URL
XS_MAP_URL=$XS_MAP_URL
RUNTIME_IMPACT=true
COPY_VERIFY=PASS
NEXT_ACTION=P26C3 production SMTP/TLS magic-link delivery and durable admin authorization boundary before first trusted-user P27 pilot
EOF
cp "$REPORT/report.txt" "$REPORT/verify.txt"
cp "$ROOT/scripts/run-step.sh" "$REPORT/executed-step.sh"
cp "$ROOT/release-info.json" "$REPORT/release-info.json"
cp "$ROOT/rollback/README.md" "$REPORT/rollback.txt"
for f in \
  pre-vm100-source-validation.txt pre-vm101-source-validation.txt pre-vm121-source-validation.txt \
  pre-vm121-live.txt pre-vm100-live.txt pre-vm101-live.txt live-test.txt \
  post-vm100-source-validation.txt post-vm101-source-validation.txt post-vm121-source-validation.txt \
  post-vm121-live.txt post-vm100-live.txt post-vm101-live.txt; do
  cp "$EVIDENCE/$f" "$REPORT/$f"
done
python3 - "$REPORT/facts.json" "$VM100_SELECTED_SELECTOR_FIRST" "$VM100_SELECTED_SELECTOR_SECOND" "$BACKUP_DIR" <<'PY'
import json,sys
out,selector1,selector2,backup=sys.argv[1:]
facts={
  "schema":"wg-paid-p26c2-r01-facts-v1",
  "result":"PASS_P26C2_CONTROLLED_LIVE_EXTERNAL_WIREGUARD_PROOF",
  "revision":"R01",
  "source_changed":False,
  "live_database_written":True,
  "database_schema_changed":False,
  "alembic_version":"0004_profile_provisioning",
  "authenticated_config_surface_live":"PASS",
  "external_client_handshake_proven":True,
  "first_external_handshake":"PASS",
  "first_internet_data_plane":"PASS",
  "old_config_revoke_effect":"PASS",
  "reissue_config_changed":True,
  "reissue_public_key_changed":True,
  "second_external_handshake":"PASS",
  "second_internet_data_plane":"PASS",
  "final_revoke_effect":"PASS",
  "vm100_selector_authority":"VM100",
  "vm100_selected_selector_first":selector1,
  "vm100_selected_selector_second":selector2,
  "synthetic_db_final_zero":True,
  "synthetic_vm100_final_zero":True,
  "secret_leakage_proof":"PASS",
  "runtime_provisioning_active":False,
  "external_onboarding_active":False,
  "public_config_qr_active":False,
  "smtp_tls_delivery_active":False,
  "encrypted_backup_present":True,
  "backup_restore_proof":"PASS",
  "backup_dir":backup,
  "beach_vm100_preserved":True,
  "beach_vm101_preserved":True,
  "vm101_wg_paid_dnat_preserved":True,
  "vm100_commit":"8c5d11b7e4b119757ea16b46775b26e0ac903d7c",
  "vm101_commit":"94a1c5627bacf9212d3fb2af1a77507ec57ff74b",
  "vm121_commit":"9bbb2aeacd669698055121a0f4fbaf5aa67720db",
  "vm121_tree":"f83f404ca097962b1d407ad5b3c32da96acd4ee4",
  "vm121_file_count":51
}
with open(out,'w',encoding='utf-8') as f:
    json.dump(facts,f,indent=2,sort_keys=True)
    f.write('\n')
PY
args=()
while IFS= read -r f; do
  args+=("$f" "$(basename "$f")")
done < <(find "$REPORT" -maxdepth 1 -type f -print | LC_ALL=C sort)
router_step_publish_payload step050m07p26c2_r01_controlled_live_external_wireguard_proof \
  "$REPORT" "$PAYLOAD" "$CURRENT" "$EVENTS" "$FINAL_ENV" "${args[@]}"
STEP_REPORT_URL="$(last_field PUBLIC_URL "$FINAL_ENV")"
router_step_phase_complete report_publish report_and_facts_published

router_step_phase_begin archive
archive_latest
router_step_phase_complete archive latest_archived
STOP_DETAIL=none
write_child PASS_P26C2_CONTROLLED_LIVE_EXTERNAL_WIREGUARD_PROOF 0
trap - ERR
exit 0
