#!/usr/bin/env bash

set -Eeuo pipefail
umask 077
export LANG=C

EXPECTED_HOSTNAME="sqjcnginx01"
EXPECTED_IPV4="10.2.203.102"
BUNDLE_ROOT="/opt/zhct-deploy"
PACKAGE_ROOT="${BUNDLE_ROOT}/packages"
RUN_ID=${1:-}
EVIDENCE_DIR="/var/backups/zhct-q041/evidence/${RUN_ID}"
VIP_RE='10\.2\.203\.(115|116|117)'
MIN_FREE_BYTES=$((9 * 1024 * 1024 * 1024))
UNITS=(nginx.service keepalived.service haproxy.service orchestrator.service sentinel5.service sentinel7.service)

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

[[ "${EUID}" -eq 0 ]] || die "must run as root"
[[ "${RUN_ID}" =~ ^q041-[0-9]{8}T[0-9]{6}[+]0800$ ]] || die "invalid Q041 run id"
[[ "$(hostname -s)" == "${EXPECTED_HOSTNAME}" ]] || die "hostname mismatch"
ip -o -4 addr show scope global | awk '{print $4}' | cut -d/ -f1 | \
  grep -Fxq "${EXPECTED_IPV4}" || die "expected IPv4 is not configured"
grep -Fq 'install_execution=PASS' "${EVIDENCE_DIR}/install-result.env" || \
  die "Q041 installation is not PASS"

/usr/local/nginx/sbin/nginx -v 2>&1 | grep -Fq 'nginx/1.26.3' || die "Nginx version mismatch"
/usr/local/sbin/keepalived --version 2>&1 | grep -Fq 'v2.3.4' || die "Keepalived version mismatch"
/usr/local/haproxy/sbin/haproxy -v 2>&1 | grep -Fq '2.8.26' || die "HAProxy version mismatch"
/opt/redis/5.0.14/bin/redis-sentinel --version | grep -Fq 'v=5.0.14' || \
  die "Redis5 Sentinel version mismatch"
/opt/redis/7.2.14/bin/redis-sentinel --version | grep -Fq 'v=7.2.14' || \
  die "Redis7 Sentinel version mismatch"
[[ -x /opt/redis/5.0.14/bin/redis-cli && -x /opt/redis/7.2.14/bin/redis-cli ]] || \
  die "Redis CLI runtime is missing"
[[ ! -e /opt/redis/5.0.14/bin/redis-server && ! -e /opt/redis/7.2.14/bin/redis-server ]] || \
  die "Redis server binary must not be installed on the Nginx role"

: >"${EVIDENCE_DIR}/rpm-nevra-verify.tsv"
rpm_count=0
while IFS= read -r -d '' rpm_file; do
  expected_nevra=$(rpm -qp --qf '%{NAME}-%{EPOCHNUM}:%{VERSION}-%{RELEASE}.%{ARCH}' "${rpm_file}")
  package_name=$(rpm -qp --qf '%{NAME}' "${rpm_file}")
  actual_nevra=$(rpm -q --qf '%{NAME}-%{EPOCHNUM}:%{VERSION}-%{RELEASE}.%{ARCH}' "${package_name}")
  [[ "${actual_nevra}" == "${expected_nevra}" ]] || die "installed NEVRA mismatch: ${package_name}"
  printf '%s\t%s\n' "${package_name}" "${actual_nevra}" >>"${EVIDENCE_DIR}/rpm-nevra-verify.tsv"
  rpm_count=$((rpm_count + 1))
done < <(find "${PACKAGE_ROOT}/rpms" -maxdepth 1 -type f -name '*.rpm' -print0 | sort -z)
[[ "${rpm_count}" -eq 18 ]] || die "expected 18 installed RPMs"

rpm -q percona-orchestrator percona-orchestrator-cli percona-orchestrator-client \
  >"${EVIDENCE_DIR}/orchestrator-rpms.txt"
if /usr/bin/orchestrator --version >"${EVIDENCE_DIR}/orchestrator-version.txt" 2>&1; then
  :
elif /usr/bin/orchestrator version >"${EVIDENCE_DIR}/orchestrator-version.txt" 2>&1; then
  :
else
  die "Orchestrator executable self-check failed"
fi

for unit in "${UNITS[@]}"; do
  systemctl cat "${unit}" >/dev/null 2>&1 || die "unit is missing: ${unit}"
  enabled_state=$(systemctl is-enabled "${unit}" 2>/dev/null || true)
  [[ "${enabled_state}" == "disabled" || "${enabled_state}" == "masked" ]] || \
    die "unit is not disabled: ${unit} (${enabled_state})"
  if systemctl is-active --quiet "${unit}"; then
    die "unit is active: ${unit}"
  fi
done

[[ "$(sysctl -n net.ipv4.ip_nonlocal_bind)" == "1" ]] || die "ip_nonlocal_bind was not applied"
[[ "$(sysctl -n net.ipv4.conf.all.arp_ignore)" == "1" ]] || die "arp_ignore was not applied"
[[ "$(sysctl -n net.ipv4.conf.all.arp_announce)" == "2" ]] || die "arp_announce was not applied"

for forbidden_path in /usr/local/php73 /usr/local/php74 /usr/local/mysql /usr/lib/emqx; do
  [[ ! -e "${forbidden_path}" ]] || die "forbidden role path exists: ${forbidden_path}"
done
for forbidden_unit in php-fpm73.service php-fpm74.service mysql56.service mysql80.service \
  redis5.service redis7.service emqx.service; do
  if systemctl cat "${forbidden_unit}" >/dev/null 2>&1; then
    die "forbidden role unit exists: ${forbidden_unit}"
  fi
done

target_processes=$(ps -eo pid,cmd | \
  grep -Ei '[n]ginx|[k]eepalived|[h]aproxy|[o]rchestrator|[r]edis-(server|sentinel)' || true)
vip_addresses=$(ip -o -4 addr show | grep -E "${VIP_RE}" || true)
[[ -z "${target_processes}" ]] || die "target process is running before temporary health checks"
[[ -z "${vip_addresses}" ]] || die "a project VIP is announced"

root_available_bytes=$(df -B1 --output=avail / | tail -n 1 | tr -d ' ')
root_total_bytes=$(df -B1 --output=size / | tail -n 1 | tr -d ' ')
root_twenty_percent_bytes=$((root_total_bytes / 5))
minimum_required_bytes=${MIN_FREE_BYTES}
if ((root_twenty_percent_bytes > minimum_required_bytes)); then
  minimum_required_bytes=${root_twenty_percent_bytes}
fi
((root_available_bytes >= minimum_required_bytes)) || die "postinstall root free space is below the gate"

{
  printf 'captured_at=%s\n' "$(date --iso-8601=seconds)"
  printf 'run_id=%s\n' "${RUN_ID}"
  printf 'nginx_version=1.26.3\n'
  printf 'keepalived_version=2.3.4\n'
  printf 'haproxy_version=2.8.26\n'
  printf 'orchestrator_rpm_version=3.2.6-22\n'
  printf 'redis5_sentinel_version=5.0.14\n'
  printf 'redis7_sentinel_version=7.2.14\n'
  printf 'installed_rpm_count=%s\n' "${rpm_count}"
  printf 'target_units_disabled_inactive=PASS\n'
  printf 'sysctl_check=PASS\n'
  printf 'role_isolation_check=PASS\n'
  printf 'vip_announcement_count=0\n'
  printf 'root_available_bytes=%s\n' "${root_available_bytes}"
  printf 'minimum_required_bytes=%s\n' "${minimum_required_bytes}"
  printf 'postinstall_static_check=PASS\n'
  printf 'temporary_health_check=NOT_PERFORMED\n'
} >"${EVIDENCE_DIR}/postinstall-static-result.env"

chmod 0600 "${EVIDENCE_DIR}"/*
printf 'Q041_POSTINSTALL_STATIC_OK\n'
cat "${EVIDENCE_DIR}/postinstall-static-result.env"
