#!/usr/bin/env bash

set -Eeuo pipefail
export LANG=C

SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)
REPO_ROOT=$(cd -- "${SCRIPT_DIR}/../../../.." && pwd -P)
STATE_FILE="${SCRIPT_DIR}/state.env"

die() {
  printf 'ERROR: %s\n' "$*" >&2
  exit 1
}

digest_file() {
  if command -v sha256sum >/dev/null 2>&1; then
    sha256sum "$1" | awk '{print $1}'
  else
    shasum -a 256 "$1" | awk '{print $1}'
  fi
}

allow_worktree=NO
if [[ $# -eq 1 && "$1" == "--allow-worktree" ]]; then
  allow_worktree=YES
elif [[ $# -ne 0 ]]; then
  die "usage: $0 [--allow-worktree]"
fi

required_files=(
  "${REPO_ROOT}/AGENTS.md"
  "${REPO_ROOT}/HEARTBEAT.md"
  "${REPO_ROOT}/tasks/QUEUE.md"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/AGENTS.md"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/HANDOFF.md"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/Q.MD"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/AUDIT.md"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-042/README.md"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-042/STEP_LOG.md"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-042/evidence/q042-evidence-q042-20260723T134134+0800-R1.tar.gz"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-042/evidence/q042-evidence-q042-20260723T134134+0800-R1.tar.gz.sha256"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-042/scripts/q042-final-audit-check.sh"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-042/scripts/q042-offline-rebuild-check.sh"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-043/README.md"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-043/STEP_LOG.md"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-043/evidence/q043-evidence-q043-20260723T195817+0800.tar.gz"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-043/evidence/q043-evidence-q043-20260723T195817+0800.tar.gz.sha256"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-043/scripts/q043-seal-check.sh"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-043/scripts/q043-postseal-recovery-finalize.sh"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-050/README.md"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-050/STEP_LOG.md"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-050/scripts/q050-baseline-backup.sh"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-050/scripts/q050-refresh-app-framework.sh"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-050/scripts/q050-download-source-assets.sh"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-050/scripts/q050-build-rpm-closure.sh"
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-050/scripts/q050-offline-assets-check.sh"
  "${SCRIPT_DIR}/decision-register.md"
  "${SCRIPT_DIR}/next-agent-prompt.md"
  "${STATE_FILE}"
  "${SCRIPT_DIR}/summary.md"
  "${SCRIPT_DIR}/verify-handoff.sh"
)

for file in "${required_files[@]}"; do
  [[ -f "${file}" ]] || die "required handoff file is missing: ${file}"
done

if [[ "${allow_worktree}" == "NO" ]]; then
  [[ "$(git -C "${REPO_ROOT}" branch --show-current)" == "master" ]] || \
    die "current Git branch is not master"
  for file in "${required_files[@]}"; do
    relative=${file#"${REPO_ROOT}/"}
    git -C "${REPO_ROOT}" ls-files --error-unmatch -- "${relative}" >/dev/null 2>&1 || \
      die "required handoff file is not tracked: ${relative}"
    git -C "${REPO_ROOT}" cat-file -e "HEAD:${relative}" 2>/dev/null || \
      die "required handoff file is not committed in HEAD: ${relative}"
  done
  git -C "${REPO_ROOT}" diff --quiet -- "${required_files[@]}" || \
    die "required handoff files have unstaged changes"
  git -C "${REPO_ROOT}" diff --cached --quiet -- "${required_files[@]}" || \
    die "required handoff files have staged changes"
  local_head=$(git -C "${REPO_ROOT}" rev-parse HEAD)
  remote_head=$(git -C "${REPO_ROOT}" rev-parse --verify origin/master 2>/dev/null) || \
    die "origin/master is unavailable; run git pull --ff-only first"
  [[ "${local_head}" == "${remote_head}" ]] || \
    die "HEAD does not match origin/master; pull or push the handoff commit first"
  live_remote_head=$(git -C "${REPO_ROOT}" ls-remote --heads origin refs/heads/master | \
    awk 'NR == 1 { print $1 }')
  [[ -n "${live_remote_head}" ]] || die "cannot read the live origin/master SHA"
  [[ "${local_head}" == "${live_remote_head}" ]] || \
    die "HEAD does not match the live origin/master; run git pull --ff-only"
fi

set -a
# shellcheck disable=SC1090
. "${STATE_FILE}"
set +a

[[ "${HANDOFF_SCHEMA_VERSION}" == "1" ]] || die "unsupported handoff schema"
[[ "${GIT_BRANCH}" == "master" ]] || die "handoff branch is not master"
[[ "${CURRENT_QUEUE_ITEM}" == "Q-050" ]] || die "current queue item is not Q-050"
[[ "${Q042_STATUS}" == "CONFIRMED_PASS" ]] || \
  die "Q-042 status is not the expected handoff state"
[[ "${Q043_STATUS}" == "SEALED_PASS" ]] || die "Q-043 is not SEALED_PASS"
[[ "${NEXT_ACTION_REQUIRES_USER_CONFIRMATION}" == "NO_TARGET_MODE" ]] || \
  die "target-mode continuation state is missing"
[[ "${LEGACY_FINAL_AUDIT_R0_R1_EXECUTION}" == "FORBIDDEN" ]] || \
  die "legacy final audit scripts are not forbidden"
[[ "${R2_REEXECUTION}" == "FORBIDDEN" ]] || die "R2 re-execution is not forbidden"
[[ "${LOCAL_EVIDENCE_VERIFY}" == "PASS" ]] || die "local evidence verification is not PASS"
[[ "${Q043_REMOTE_EXECUTION}" == "COMPLETED_WITH_POSTSEAL_RECOVERY_PASS" ]] || \
  die "Q-043 remote execution state is not complete"
[[ "${Q043_LOCAL_EVIDENCE_VERIFY}" == "PASS" ]] || \
  die "Q-043 local evidence verification is not PASS"
[[ "${Q043_POST_SEAL_REBOOT_RECONNECT}" == "FORBIDDEN" ]] || \
  die "Q-043 post-seal reconnect boundary is missing"
[[ "${Q050_STATUS}" == "PREPARED_BLOCKED_BASTION_LOGIN" ]] || \
  die "Q-050 handoff state is unexpected"

final_script="${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-042/scripts/q042-final-audit-check.sh"
b4_script="${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-042/scripts/q042-offline-rebuild-check.sh"
q043_script="${REPO_ROOT}/${Q043_CANONICAL_SCRIPT}"
q043_recovery_script="${REPO_ROOT}/${Q043_RECOVERY_SCRIPT}"
[[ "$(digest_file "${final_script}")" == "${REMOTE_FINAL_AUDIT_SHA256}" ]] || \
  die "canonical R2 script SHA256 mismatch"
[[ "$(digest_file "${b4_script}")" == "${REMOTE_B4_SCRIPT_SHA256}" ]] || \
  die "canonical B4 script SHA256 mismatch"

bash -n "${final_script}"
bash -n "${b4_script}"
[[ "$(digest_file "${q043_script}")" == "${Q043_CANONICAL_SCRIPT_SHA256}" ]] || \
  die "canonical Q-043 script SHA256 mismatch"
bash -n "${q043_script}"
[[ "$(digest_file "${q043_recovery_script}")" == "${Q043_RECOVERY_SCRIPT_SHA256}" ]] || \
  die "canonical Q-043 recovery script SHA256 mismatch"
bash -n "${q043_recovery_script}"
for q050_pair in \
  "${Q050_BASELINE_SCRIPT}:${Q050_BASELINE_SCRIPT_SHA256}" \
  "${Q050_FRAMEWORK_REFRESH_SCRIPT}:${Q050_FRAMEWORK_REFRESH_SCRIPT_SHA256}" \
  "${Q050_SOURCE_DOWNLOAD_SCRIPT}:${Q050_SOURCE_DOWNLOAD_SCRIPT_SHA256}" \
  "${Q050_RPM_CLOSURE_SCRIPT}:${Q050_RPM_CLOSURE_SCRIPT_SHA256}" \
  "${Q050_OFFLINE_ASSETS_CHECK_SCRIPT}:${Q050_OFFLINE_ASSETS_CHECK_SCRIPT_SHA256}"; do
  q050_path=${q050_pair%%:*}
  q050_sha=${q050_pair#*:}
  [[ "$(digest_file "${REPO_ROOT}/${q050_path}")" == "${q050_sha}" ]] || \
    die "Q-050 script SHA256 mismatch: ${q050_path}"
  bash -n "${REPO_ROOT}/${q050_path}"
done
grep -Fq '用户于 2026-07-23 19:16 +0800 确认 Q-042' \
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/Q.MD" || \
  die "Q.MD Q-042 confirmation is missing"
grep -Fq 'Q-050，App01 基线、备份与离线资产闭环' \
  "${REPO_ROOT}/work_sanquan_frontdesk_deployment/HANDOFF.md" || \
  die "HANDOFF.md Q-050 state is missing"
grep -Fq 'Q-043 已封板 PASS' "${SCRIPT_DIR}/summary.md" || \
  die "Q-043 completed handoff state is missing"

archive="${REPO_ROOT}/work_sanquan_frontdesk_deployment/deployment-records/Q-042/evidence/q042-evidence-q042-20260723T134134+0800-R1.tar.gz"
archive_sha="${archive}.sha256"
[[ "$(digest_file "${archive}")" == "${FINAL_ARCHIVE_SHA256}" ]] || \
  die "final archive SHA256 mismatch"
[[ "$(awk 'NR == 1 { print $1 }' "${archive_sha}")" == "${FINAL_ARCHIVE_SHA256}" ]] || \
  die "final archive checksum file mismatch"

verify_dir=$(mktemp -d "${TMPDIR:-/tmp}/q042-handoff-verify.XXXXXX")
trap 'rm -rf -- "${verify_dir}"' EXIT
tar -xzf "${archive}" -C "${verify_dir}"
(
  cd "${verify_dir}"
  shasum -a 256 -c q042-final-evidence-index.sha256 >/dev/null
  [[ "$(digest_file q042-final-evidence-index.sha256)" == "${FINAL_EVIDENCE_INDEX_SHA256}" ]]
  [[ "$(wc -l < q042-final-evidence-index.sha256 | tr -d ' ')" == "${FINAL_EVIDENCE_FILE_COUNT}" ]]
  [[ "$(grep -Ec '^v([1-9]|10)_.+=PASS$' final-audit-result.env)" -eq 10 ]]
  grep -Fxq 'sensitive_scan=PASS' final-audit-result.env
  grep -Fxq 'target_units_quiescent=PASS' final-audit-result.env
  grep -Fxq 'target_listener_count=0' final-audit-result.env
  grep -Fxq 'vip_announcement_count=0' final-audit-result.env
  grep -Fxq 'q043_execution=LOCKED_PENDING_USER_CONFIRMATION' final-audit-result.env
  grep -Fxq 'final_audit_check=PASS' final-audit-result.env
) || die "final evidence archive verification failed"

q043_archive="${REPO_ROOT}/${Q043_FINAL_ARCHIVE}"
q043_archive_sha="${q043_archive}.sha256"
[[ "$(digest_file "${q043_archive}")" == "${Q043_FINAL_ARCHIVE_SHA256}" ]] || \
  die "Q-043 final archive SHA256 mismatch"
[[ "$(awk 'NR == 1 { print $1 }' "${q043_archive_sha}")" == "${Q043_FINAL_ARCHIVE_SHA256}" ]] || \
  die "Q-043 final archive checksum file mismatch"

q043_verify_dir=$(mktemp -d "${TMPDIR:-/tmp}/q043-handoff-verify.XXXXXX")
tar -xzf "${q043_archive}" -C "${q043_verify_dir}"
q043_evidence_dir="${q043_verify_dir}/${Q043_RUN_ID}"
(
  cd "${q043_evidence_dir}"
  shasum -a 256 -c q043-final-evidence-index.sha256 >/dev/null
  [[ "$(digest_file q043-final-evidence-index.sha256)" == "${Q043_FINAL_EVIDENCE_INDEX_SHA256}" ]]
  [[ "$(wc -l < q043-final-evidence-index.sha256 | tr -d ' ')" == "${Q043_FINAL_EVIDENCE_FILE_COUNT}" ]]
  [[ "$(grep -Ec '^(v([1-9]|10)_.+|target_units_quiescent|target_listener_count|vip_announcement_count|machine_id_bytes|ssh_host_key_file_count|sensitive_scan|template_state|guest_reboot_or_reconnect|next_task_execution|final_check)=' final-result.env)" -eq "${Q043_FINAL_RESULT_GATE_COUNT}" ]]
  grep -Fxq 'v10_post_clone_dry_run_and_evidence=PASS' final-result.env
  grep -Fxq 'postseal_recovery_finalizer=PASS' final-result.env
  grep -Fxq 'target_units_quiescent=PASS' final-result.env
  grep -Fxq 'target_listener_count=0' final-result.env
  grep -Fxq 'vip_announcement_count=0' final-result.env
  grep -Fxq 'machine_id_bytes=0' final-result.env
  grep -Fxq 'ssh_host_key_file_count=0' final-result.env
  grep -Fxq 'sensitive_scan=PASS' final-result.env
  grep -Fxq 'template_state=SEALED_AWAITING_CUSTOMER_APPLICATION' final-result.env
  grep -Fxq 'guest_reboot_or_reconnect=FORBIDDEN' final-result.env
  grep -Fxq 'final_check=PASS' final-result.env
) || die "Q-043 final evidence archive verification failed"

(
  cd "${REPO_ROOT}"
  git diff --check
  python3 control/scripts/task_index.py validate
)

printf 'SANQUAN_HANDOFF_VERIFY_OK\n'
