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

EXPECTED_HOSTNAME=sqjcDB01
EXPECTED_IP=10.2.208.106
PREVIOUS_RUN=q121-20260729T182343+0800
PREVIOUS_EVIDENCE="/var/backups/zhct-q121-122/$PREVIOUS_RUN"
PREVIOUS_ARCHIVE="/root/sanquan-mysql-q121-evidence-$PREVIOUS_RUN.tar.gz"
EXPECTED_PREVIOUS_ARCHIVE_SHA256=b69c6df13ed4b3ef592d5d302ff7702f76d3c71da6e7a8765f1017076bdc745c
RUNTIME=/opt/zhct-deploy/common/lib/runtime.sh
EXPECTED_RUNTIME_SHA256=2d9acb64fca36ff23061cf8da0dfb25c384f21fd00b39e750c4afd3d30350dc0
HOOKS=/opt/zhct-deploy/roles/mysql/hooks.sh
EXPECTED_HOOKS_SHA256=8dd8ad31318a6111fdaf9e0d346dad12fa5da5e629b2dfd429a2e66a3e5e016a
ARCHIVE=/root/sanquan-mysql-q121-122-offline-package-v5-20260729.tar.gz
EXPECTED_ARCHIVE_SHA256=5cafeffebe365fe7753c9a9b6d6f2380b53ce33d7d5ce8be0c12a8134f6f709b
EXTRACT_DIR=/root/sanquan-mysql-q121-122-offline-package-v5-20260729-v7-run

identity_matches() {
  local actual_hostname=$1 ipv4_lines=$2
  local actual_lower expected_lower
  actual_lower=$(printf '%s' "$actual_hostname" | tr '[:upper:]' '[:lower:]')
  expected_lower=$(printf '%s' "$EXPECTED_HOSTNAME" | tr '[:upper:]' '[:lower:]')
  [[ "$actual_lower" == "$expected_lower" ]] || return 1
  awk -v expected="$EXPECTED_IP" '
    {
      address=$0
      sub(/\/.*/, "", address)
      if (address == expected) found=1
    }
    END {exit !found}
  ' <<<"$ipv4_lines"
}

if [[ ${1:-} == --self-test-wrong-host ]]; then
  if identity_matches wrong-host "$EXPECTED_IP"; then
    echo "ERROR: wrong-host negative gate unexpectedly passed"
    exit 1
  fi
  echo "Q121_V7_WRONG_HOST_NEGATIVE_TEST_PASS"
  exit 0
fi

[[ $# -eq 0 ]] || {
  echo "ERROR: this wrapper accepts no arguments"
  exit 2
}

[[ $EUID -eq 0 ]] || {
  echo "ERROR: root is required"
  exit 1
}

actual_hostname=$(hostname -s)
actual_ipv4=$(ip -o -4 addr show scope global | awk '{print $4}')
identity_matches "$actual_hostname" "$actual_ipv4" || {
  printf 'ERROR: target identity mismatch: expected_hostname=%s expected_ip=%s actual_hostname=%s\n' \
    "$EXPECTED_HOSTNAME" "$EXPECTED_IP" "$actual_hostname"
  exit 1
}

RUN_ID="q121-schema-allowlist-v7-$(date '+%Y%m%dT%H%M%S%z')"
EVIDENCE_DIR="/var/backups/zhct-q121-122/$RUN_ID"
AUDIT_LOG="$EVIDENCE_DIR/manual-wrapper.log"
RESULT_FILE="$EVIDENCE_DIR/manual-wrapper-result.env"
umask 077
install -d -m 0700 -o root -g root "$EVIDENCE_DIR"
exec > >(tee -a "$AUDIT_LOG") 2>&1

finish() {
  local rc=$?
  trap - EXIT
  {
    printf 'finished_at=%s\n' "$(date --iso-8601=seconds)"
    printf 'target_hostname=%s\n' "$EXPECTED_HOSTNAME"
    printf 'target_ip=%s\n' "$EXPECTED_IP"
    printf 'previous_failed_run=%s\n' "$PREVIOUS_RUN"
    printf 'action=q121_v5_package_schema_allowlist_execute\n'
    printf 'exit_code=%s\n' "$rc"
  } >"$RESULT_FILE"
  printf 'audit_log=%s\n' "$AUDIT_LOG"
  printf 'result_file=%s\n' "$RESULT_FILE"
  printf 'END MYSQL01_Q121_SCHEMA_ALLOWLIST_EXECUTE_V7 RC=%s\n' "$rc"
  exit "$rc"
}
trap finish EXIT

printf 'BEGIN MYSQL01_Q121_SCHEMA_ALLOWLIST_EXECUTE_V7\n'
printf 'started_at=%s\n' "$(date --iso-8601=seconds)"
printf 'target_identity=PASS\n'
printf 'expected_hostname=%s\nexpected_ip=%s\n' "$EXPECTED_HOSTNAME" "$EXPECTED_IP"

[[ -f "$PREVIOUS_EVIDENCE/result.env" ]] || {
  echo "ERROR: previous Q-121 v6 result evidence is missing"
  exit 1
}
grep -Fxq 'result=FAIL_ROLLED_BACK' "$PREVIOUS_EVIDENCE/result.env" || {
  echo "ERROR: previous Q-121 v6 rollback receipt is invalid"
  exit 1
}
grep -Fxq 'replication=NOT_PERFORMED_Q221_GATE' "$PREVIOUS_EVIDENCE/result.env"
grep -Fxq 'business_sql=NOT_PERFORMED_Q261_GATE' "$PREVIOUS_EVIDENCE/result.env"
[[ -f "$PREVIOUS_ARCHIVE" ]] || {
  echo "ERROR: previous Q-121 v6 archive is missing"
  exit 1
}
[[ $(sha256sum "$PREVIOUS_ARCHIVE" | awk '{print $1}') == "$EXPECTED_PREVIOUS_ARCHIVE_SHA256" ]] || {
  echo "ERROR: previous Q-121 v6 archive SHA256 mismatch"
  exit 1
}
printf 'previous_v6_failure_rollback_receipt=PASS\n'

[[ -f "$RUNTIME" && ! -L "$RUNTIME" ]] || {
  echo "ERROR: locked runtime is missing or is a symlink"
  exit 1
}
[[ -f "$HOOKS" && ! -L "$HOOKS" ]] || {
  echo "ERROR: locked MySQL hooks file is missing or is a symlink"
  exit 1
}
[[ $(sha256sum "$RUNTIME" | awk '{print $1}') == "$EXPECTED_RUNTIME_SHA256" ]] || {
  echo "ERROR: runtime SHA256 is not the locked repaired version"
  exit 1
}
[[ $(sha256sum "$HOOKS" | awk '{print $1}') == "$EXPECTED_HOOKS_SHA256" ]] || {
  echo "ERROR: MySQL hooks SHA256 is not the locked runuser version"
  exit 1
}
[[ $(stat -c '%a %U:%G' /etc) == '755 root:root' ]] || {
  echo "ERROR: /etc metadata is not the repaired state"
  exit 1
}
runuser -u mysql -- test -r /etc/my56.cnf
runuser -u mysql -- test -r /etc/my80.cnf
printf 'locked_framework_gate=PASS\n'

[[ -f "$ARCHIVE" ]] || {
  echo "ERROR: v5 Q-121/Q-122 archive is missing"
  exit 1
}
actual_archive_sha256=$(sha256sum "$ARCHIVE" | awk '{print $1}')
[[ "$actual_archive_sha256" == "$EXPECTED_ARCHIVE_SHA256" ]] || {
  printf 'ERROR: archive SHA256 mismatch: expected=%s actual=%s\n' \
    "$EXPECTED_ARCHIVE_SHA256" "$actual_archive_sha256"
  exit 1
}
printf 'archive_sha256=%s\narchive_sha256_check=PASS\n' "$actual_archive_sha256"

[[ ! -e "$EXTRACT_DIR" ]] || {
  printf 'ERROR: extract target already exists: %s\n' "$EXTRACT_DIR"
  exit 1
}
install -d -m 0700 -o root -g root "$EXTRACT_DIR"
tar --extract --gzip --file="$ARCHIVE" --directory="$EXTRACT_DIR" --no-same-owner

cd "$EXTRACT_DIR"
sha256sum -c SHA256SUMS
bash -n q121-122-mysql.sh
bash -n framework/common/lib/runtime.sh
bash -n framework/roles/mysql/hooks.sh
bash q121-122-mysql.sh --static-validate
bash q121-122-mysql.sh --self-test-schema-contract
grep -Fq 'mysql56_infrastructure_namespace=' q121-122-mysql.sh
grep -Fq "name '*.frm'" q121-122-mysql.sh
printf 'schema_allowlist_regression_gate=PASS\n'

bash q121-122-mysql.sh q121 execute

printf 'MYSQL01_Q121_SCHEMA_ALLOWLIST_EXECUTE_V7_PASS\n'
