#!/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"
RUN_ID=${1:-}
CONFIRM=${2:-}
EVIDENCE_DIR="/var/backups/zhct-q041/evidence/${RUN_ID}"
INSTALL_LOG="${EVIDENCE_DIR}/install-role.log"
UNITS=(nginx.service keepalived.service haproxy.service orchestrator.service sentinel5.service sentinel7.service)

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

on_error() {
  local exit_code=$?
  for unit in "${UNITS[@]}"; do
    systemctl disable --now "${unit}" >/dev/null 2>&1 || true
  done
  {
    printf 'captured_at=%s\n' "$(date --iso-8601=seconds)"
    printf 'run_id=%s\n' "${RUN_ID}"
    printf 'install_execution=FAILED\n'
    printf 'exit_code=%s\n' "${exit_code}"
    printf 'target_units_forced_inactive=ATTEMPTED\n'
    printf 'rollback_required=YES\n'
  } >"${EVIDENCE_DIR}/install-result.env"
  chmod 0600 "${EVIDENCE_DIR}/install-result.env"
  exit "${exit_code}"
}

[[ "${EUID}" -eq 0 ]] || die "must run as root"
[[ "${RUN_ID}" =~ ^q041-[0-9]{8}T[0-9]{6}[+]0800$ ]] || die "invalid Q041 run id"
case "${CONFIRM}" in
  --execute-q041-install|--resume-q041-install) ;;
  *)
    die "explicit Q041 install or resume flag is required"
    ;;
esac
[[ "$(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"
[[ -s "${EVIDENCE_DIR}/preinstall-result.env" ]] || die "preinstall result is missing"
grep -Fq 'preinstall_check=PASS' "${EVIDENCE_DIR}/preinstall-result.env" || \
  die "preinstall gate is not PASS"
grep -Fq 'install_execution=NOT_PERFORMED' "${EVIDENCE_DIR}/preinstall-result.env" || \
  die "preinstall state does not allow installation"

install -d -m 0700 -o root -g root "${EVIDENCE_DIR}"
exec 9>/run/lock/zhct-q041-install.lock
flock -n 9 || die "another Q041 installation process is running"
case "${CONFIRM}" in
  --execute-q041-install)
    [[ ! -e "${EVIDENCE_DIR}/install-started.marker" ]] || die "this Q041 run was already started"
    touch "${EVIDENCE_DIR}/install-started.marker"
    ;;
  --resume-q041-install)
    [[ -e "${EVIDENCE_DIR}/install-started.marker" ]] || die "no interrupted Q041 run exists"
    grep -Fq 'install_execution=FAILED' "${EVIDENCE_DIR}/install-result.env" || \
      die "only a failed Q041 run can be resumed"
    ;;
esac
chmod 0600 "${EVIDENCE_DIR}/install-started.marker"
trap on_error ERR

dnf_history_id_before=$(awk -F= '$1 == "dnf_history_id_before" {print $2}' \
  "${EVIDENCE_DIR}/preinstall-result.env")
dnf_history_id_before=${dnf_history_id_before:-0}
printf '%s\n' "${dnf_history_id_before}" >"${EVIDENCE_DIR}/dnf-history-id-before.txt"

RUN_ID="${RUN_ID}" \
BACKUP_ROOT="/var/backups/zhct-q041/files" \
"${BUNDLE_ROOT}/common/scripts/install-role.sh" \
  --role nginx \
  --bundle-root "${BUNDLE_ROOT}" \
  >"${INSTALL_LOG}" 2>&1

dnf_history_id_after=$(dnf history list | awk '$1 ~ /^[0-9]+$/ {print $1; exit}')
dnf_history_id_after=${dnf_history_id_after:-0}
((dnf_history_id_after > dnf_history_id_before)) || \
  die "DNF history did not advance after installation"
printf '%s\n' "${dnf_history_id_after}" >"${EVIDENCE_DIR}/dnf-history-id-after.txt"
dnf history info "${dnf_history_id_after}" >"${EVIDENCE_DIR}/dnf-history-install.txt" 2>&1
grep -Fq '/opt/zhct-deploy/packages/rpms/' "${EVIDENCE_DIR}/dnf-history-install.txt" || \
  die "latest DNF transaction is not the Q041 local RPM transaction"
for package in percona-orchestrator percona-orchestrator-cli percona-orchestrator-client; do
  grep -Fq "${package}" "${EVIDENCE_DIR}/dnf-history-install.txt" || \
    die "Q041 DNF transaction does not contain ${package}"
done
if grep -Eiq '^[[:space:]]*(Upgrade|Downgrade|Erase|Remove|Reinstall|Obsolete)[[:space:]]' \
  "${EVIDENCE_DIR}/dnf-history-install.txt"; then
  die "Q041 DNF transaction contains a non-install action"
fi
rpm -qa >"${EVIDENCE_DIR}/rpm-list-after-install.txt"
systemctl list-unit-files --type=service --no-pager \
  >"${EVIDENCE_DIR}/unit-files-after-install.txt"

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

{
  printf 'captured_at=%s\n' "$(date --iso-8601=seconds)"
  printf 'run_id=%s\n' "${RUN_ID}"
  printf 'dnf_history_id_before=%s\n' "${dnf_history_id_before}"
  printf 'dnf_history_id_after=%s\n' "${dnf_history_id_after}"
  printf 'role_install=PASS\n'
  printf 'target_units_disabled_inactive=PASS\n'
  printf 'install_execution=PASS\n'
  printf 'temporary_health_check=NOT_PERFORMED\n'
  printf 'rollback_required=NO\n'
} >"${EVIDENCE_DIR}/install-result.env"

trap - ERR
chmod 0600 "${EVIDENCE_DIR}"/*
printf 'Q041_INSTALL_OK\n'
cat "${EVIDENCE_DIR}/install-result.env"
