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

EXPECTED_HOSTNAME=sqjcDB01
EXPECTED_IP=10.2.208.106
EVIDENCE_RUN=q121-20260729T182343+0800
SOURCE_EVIDENCE_DIR="/var/backups/zhct-q121-122/$EVIDENCE_RUN"
SOURCE_ARCHIVE="/root/sanquan-mysql-q121-evidence-$EVIDENCE_RUN.tar.gz"

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_V6_SCHEMA_DIAGNOSTIC_WRONG_HOST_NEGATIVE_TEST_PASS"
  exit 0
fi

[[ $# -eq 0 ]] || {
  echo "ERROR: this diagnostic 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
}

[[ -d "$SOURCE_EVIDENCE_DIR" ]] || {
  printf 'ERROR: source evidence directory is missing: %s\n' "$SOURCE_EVIDENCE_DIR"
  exit 1
}

RUN_ID="q121-v6-schema-readonly-diagnostic-$(date '+%Y%m%dT%H%M%S%z')"
AUDIT_DIR="/var/backups/zhct-q121-122/$RUN_ID"
AUDIT_LOG="$AUDIT_DIR/manual-readonly-diagnostic.log"
RESULT_FILE="$AUDIT_DIR/manual-readonly-diagnostic-result.env"
umask 077
install -d -m 0700 -o root -g root "$AUDIT_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 'source_evidence_run=%s\n' "$EVIDENCE_RUN"
    printf 'action=readonly_schema_and_rollback_diagnostic\n'
    printf 'mysql_mutation=ZERO\n'
    printf 'unit_mutation=ZERO\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_V6_SCHEMA_ROLLBACK_READONLY_DIAGNOSTIC RC=%s\n' "$rc"
  exit "$rc"
}
trap finish EXIT

printf 'BEGIN MYSQL01_Q121_V6_SCHEMA_ROLLBACK_READONLY_DIAGNOSTIC\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"
printf 'source_evidence_run=%s\n' "$EVIDENCE_RUN"

printf '\n=== RESULT AND READ-ONLY SQL EVIDENCE ===\n'
for name in \
  action-result.env \
  result.env \
  mysql56-schemas.txt \
  mysql80-schemas.txt \
  mysql56-replication-status.txt \
  mysql80-replication-status.txt \
  units-after-rollback.tsv \
  listeners-after-rollback.txt
do
  printf '\n--- %s ---\n' "$name"
  if [[ -f "$SOURCE_EVIDENCE_DIR/$name" ]]; then
    nl -ba "$SOURCE_EVIDENCE_DIR/$name"
  else
    echo ABSENT
  fi
done

printf '\n=== FAILED DATA TOP LEVEL ===\n'
find \
  "$SOURCE_EVIDENCE_DIR/failed-data/mysql56" \
  "$SOURCE_EVIDENCE_DIR/failed-data/mysql80" \
  -mindepth 1 -maxdepth 1 -printf '%M %u:%g %p\n' 2>&1 | sort

printf '\n=== FORMAL DATA TOP LEVEL ===\n'
find /data/mysql56 /data/mysql80 \
  -mindepth 1 -maxdepth 1 -printf '%M %u:%g %p\n' 2>&1 | sort

printf '\n=== UNIT STATE ===\n'
for unit in \
  mysql56.service \
  mysql80.service \
  mysql-health56.service \
  mysql-health80.service
do
  printf '%s enabled=%s active=%s\n' \
    "$unit" \
    "$(systemctl is-enabled "$unit" 2>&1 || true)" \
    "$(systemctl is-active "$unit" 2>&1 || true)"
done

printf '\n=== MYSQL PROCESSES AND TARGET LISTENERS ===\n'
pgrep -a -x mysqld || true
ss -lntup | grep -E ':(3306|3308|9201|9202|33060)([[:space:]]|$)' || true

printf '\n=== SOURCE ARCHIVE ===\n'
if [[ -f "$SOURCE_ARCHIVE" ]]; then
  stat -c 'mode=%a owner=%U:%G bytes=%s path=%n' "$SOURCE_ARCHIVE"
  sha256sum "$SOURCE_ARCHIVE"
else
  echo ABSENT
fi

printf 'Q121_V6_SCHEMA_ROLLBACK_READONLY_DIAGNOSTIC_OK\n'
