#!/usr/bin/env bash
set -Eeuo pipefail
umask 077
export LC_ALL=C

EXPECTED_HOSTNAME=sqjcredis01
EXPECTED_IPV4=10.2.203.112
EXPECTED_BASELINE_DNF_ID=1
EXPECTED_MANIFEST_SHA256=ad7e8de942afe7f404c7bc7706e11f7a9f5053f75976c65b71429da466cdfbf5
EXPECTED_ROLLBACK_SHA256=1cea3a0aeb70a4e5ddcf3ec4af4c7f62d611b345b2d9521abcca6500a2715bf9
EXPECTED_SYSTEM_PARAMS_SHA256=b0887a895d0327e6e5130335bdf31bc7639cfdcf6fb4396c5ff1be34c53a51bf
RUN_ID=${1:-}
CONFIRM=${2:-}
EVIDENCE_DIR="/var/backups/zhct-q070/evidence/${RUN_ID}"
PACKAGE_ROOT=/opt/zhct-deploy/packages
ROLLBACK_SCRIPT=/root/redis01-fresh-install-rollback-1cea3a0a.sh
SYSTEM_PARAMS_SCRIPT=/root/redis01-system-params-b0887a89.sh
TX_FILE="${EVIDENCE_DIR}/q071-dnf-transaction-id.txt"
INSTALL_RESULT="${EVIDENCE_DIR}/q071-install-result.env"
INSTALLED_NEVRA="${EVIDENCE_DIR}/q071-installed-nevra.txt"
DNF_LOG="${EVIDENCE_DIR}/q071-dnf-install.log"
HISTORY_INFO="${EVIDENCE_DIR}/q071-dnf-history-info.txt"

rpms=(
  "${PACKAGE_ROOT}/rpms/jq-1.8.2-1.oe2403sp1.x86_64.rpm"
  "${PACKAGE_ROOT}/rpms/oniguruma-6.9.9-1.oe2403sp1.x86_64.rpm"
  "${PACKAGE_ROOT}/rpms/percona-orchestrator-3.2.6-22.el8.x86_64.rpm"
  "${PACKAGE_ROOT}/rpms/percona-orchestrator-cli-3.2.6-22.el8.x86_64.rpm"
  "${PACKAGE_ROOT}/rpms/percona-orchestrator-client-3.2.6-22.el8.x86_64.rpm"
)
package_names=(
  jq oniguruma percona-orchestrator
  percona-orchestrator-cli percona-orchestrator-client
)
expected_nevra=(
  'jq-0:1.8.2-1.oe2403sp1.x86_64'
  'oniguruma-0:6.9.9-1.oe2403sp1.x86_64'
  'percona-orchestrator-2:3.2.6-22.el8.x86_64'
  'percona-orchestrator-cli-2:3.2.6-22.el8.x86_64'
  'percona-orchestrator-client-2:3.2.6-22.el8.x86_64'
)

mutation_committed=0
installed_tx=
expected_tmp=
current_tmp=
history_tmp=
verify_db=

die() { printf 'ERROR: %s\n' "$*" >&2; exit 1; }
latest_dnf_id() {
  dnf history list 2>/dev/null |
    awk 'NR > 2 && $1 ~ /^[0-9]+$/ {print $1; exit}'
}
target_listener_present() {
  ss -lntupH |
    grep -Eq ':(6379|6387|26379|26387|3000|10008|16379|16387|36379|36387)([[:space:]]|$)'
}
cleanup() {
  [[ -z "${expected_tmp}" ]] || rm -f -- "${expected_tmp}"
  [[ -z "${current_tmp}" ]] || rm -f -- "${current_tmp}"
  [[ -z "${history_tmp}" ]] || rm -f -- "${history_tmp}"
  [[ -z "${verify_db}" ]] || rm -rf -- "${verify_db}"
}
emergency_undo() {
  local rc=$?
  trap - ERR
  set +e
  if [[ "${mutation_committed}" -eq 0 && -n "${installed_tx}" &&
    "${installed_tx}" =~ ^[0-9]+$ ]]; then
    dnf history undo -y "${installed_tx}" \
      >"${EVIDENCE_DIR}/q071-emergency-undo-${installed_tx}.log" 2>&1
    undo_rc=$?
    {
      printf 'install_result=FAIL_POST_INSTALL_VALIDATION\n'
      printf 'run_id=%s\n' "${RUN_ID}"
      printf 'dnf_transaction_id=%s\n' "${installed_tx}"
      printf 'emergency_undo_rc=%s\n' "${undo_rc}"
    } >"${EVIDENCE_DIR}/q071-install-failure.env"
  fi
  cleanup
  printf 'ERROR: Q071 RPM install failed; inspect evidence directory\n' >&2
  exit "${rc}"
}
trap emergency_undo ERR

[[ "${EUID}" -eq 0 ]] || die 'must run as root'
[[ "${RUN_ID}" =~ ^q070-[0-9]{8}T[0-9]{6}[+]0800$ ]] || die 'invalid Q070 run id'
[[ "${CONFIRM}" == --execute-q071-rpm-install ]] ||
  die 'explicit RPM install flag is required'
[[ "$(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'

for file in \
  "${EVIDENCE_DIR}/baseline-result.env" \
  "${EVIDENCE_DIR}/dnf-history-id-before.txt" \
  "${PACKAGE_ROOT}/rpms.sha256" \
  "${PACKAGE_ROOT}/openeuler-packaging-key.asc" \
  "${PACKAGE_ROOT}/percona-packaging-key.asc" \
  "${ROLLBACK_SCRIPT}" "${SYSTEM_PARAMS_SCRIPT}"; do
  [[ -s "${file}" ]] || die "required input missing: ${file}"
done
for file in "${TX_FILE}" "${INSTALL_RESULT}" "${INSTALLED_NEVRA}" \
  "${DNF_LOG}" "${HISTORY_INFO}" "${EVIDENCE_DIR}/q071-install-failure.env"; do
  [[ ! -e "${file}" && ! -L "${file}" ]] ||
    die "Q071 receipt already exists: ${file}"
done
grep -Fxq 'baseline=PASS' "${EVIDENCE_DIR}/baseline-result.env" ||
  die 'baseline is not PASS'
grep -Fxq "run_id=${RUN_ID}" "${EVIDENCE_DIR}/baseline-result.env" ||
  die 'baseline run id mismatch'
grep -Fxq 'install_execution=NOT_PERFORMED' "${EVIDENCE_DIR}/baseline-result.env" ||
  die 'baseline install state mismatch'
baseline_dnf_id=$(tr -cd '0-9' <"${EVIDENCE_DIR}/dnf-history-id-before.txt")
[[ "${baseline_dnf_id}" == "${EXPECTED_BASELINE_DNF_ID}" ]] ||
  die 'baseline DNF id mismatch'
[[ "$(latest_dnf_id)" == "${EXPECTED_BASELINE_DNF_ID}" ]] ||
  die 'current DNF history no longer matches baseline'
printf '%s  %s\n' "${EXPECTED_MANIFEST_SHA256}" \
  "${PACKAGE_ROOT}/rpms.sha256" | sha256sum -c - >/dev/null ||
  die 'RPM manifest SHA256 mismatch'
(
  cd "${PACKAGE_ROOT}"
  sha256sum -c rpms.sha256 >/dev/null
) || die 'RPM closure SHA256 mismatch'
printf '%s  %s\n' "${EXPECTED_ROLLBACK_SHA256}" "${ROLLBACK_SCRIPT}" |
  sha256sum -c - >/dev/null || die 'rollback script SHA256 mismatch'
printf '%s  %s\n' "${EXPECTED_SYSTEM_PARAMS_SHA256}" "${SYSTEM_PARAMS_SCRIPT}" |
  sha256sum -c - >/dev/null || die 'system params script SHA256 mismatch'
bash -n "${ROLLBACK_SCRIPT}"
bash -n "${SYSTEM_PARAMS_SCRIPT}"
"${SYSTEM_PARAMS_SCRIPT}" --check
[[ "$(systemctl is-enabled zhct-redis-thp.service)" == enabled ]] ||
  die 'THP unit is not enabled'
[[ "$(systemctl is-active zhct-redis-thp.service)" == active ]] ||
  die 'THP unit is not active'

for package in "${package_names[@]}"; do
  ! rpm -q "${package}" >/dev/null 2>&1 ||
    die "package is already installed: ${package}"
done
for unit in orchestrator redis5 redis7 sentinel5 sentinel7; do
  ! systemctl is-active --quiet "${unit}.service" ||
    die "target unit is active before install: ${unit}"
done
! target_listener_present || die 'target listener exists before install'

verify_db=$(mktemp -d /var/tmp/redis01-install-rpmdb.XXXXXX)
rpm --dbpath "${verify_db}" --initdb
rpm --dbpath "${verify_db}" --import \
  "${PACKAGE_ROOT}/openeuler-packaging-key.asc" \
  "${PACKAGE_ROOT}/percona-packaging-key.asc"
for rpm_file in "${rpms[@]}"; do
  rpm --dbpath "${verify_db}" --define '_pkgverify_level signature' \
    -K "${rpm_file}" | grep -Fq 'digests signatures OK'
done

expected_tmp=$(mktemp /var/tmp/redis01-install-expected.XXXXXX)
current_tmp=$(mktemp /var/tmp/redis01-install-current.XXXXXX)
history_tmp=$(mktemp /var/tmp/redis01-install-history.XXXXXX)
printf '%s\n' "${expected_nevra[@]}" | sort >"${expected_tmp}"

dnf --disablerepo='*' --setopt=strict=True \
  --setopt=install_weak_deps=False --setopt=localpkg_gpgcheck=False \
  -y install "${rpms[@]}" >"${DNF_LOG}" 2>&1
installed_tx=$(latest_dnf_id)
[[ "${installed_tx}" =~ ^[0-9]+$ ]] || die 'new DNF transaction id is invalid'
(( installed_tx > EXPECTED_BASELINE_DNF_ID )) ||
  die 'new DNF transaction does not follow baseline'

rpm -q --qf '%{NAME}-%{EPOCHNUM}:%{VERSION}-%{RELEASE}.%{ARCH}\n' \
  "${package_names[@]}" | sort >"${current_tmp}"
cmp -s "${expected_tmp}" "${current_tmp}" ||
  die 'installed NEVRA is not the exact expected five-package set'
dnf history info "${installed_tx}" >"${history_tmp}" 2>&1
grep -Eq '^Return-Code[[:space:]]*:[[:space:]]*Success' "${history_tmp}" ||
  die 'DNF transaction did not succeed'
grep -Eq '^Command Line[[:space:]]*:.*[[:space:]]install[[:space:]]' "${history_tmp}" ||
  die 'DNF transaction command is not install'
install_lines=$(grep -Ec '^[[:space:]]+Install[[:space:]]' "${history_tmp}" || true)
[[ "${install_lines}" -eq 5 ]] || die 'DNF transaction is not exactly five installs'
for package in "${package_names[@]}"; do
  grep -Eq "^[[:space:]]+Install[[:space:]]+${package}-[0-9]" "${history_tmp}" ||
    die "DNF transaction missing install action: ${package}"
done
if grep -Eiq '^[[:space:]]+(Upgrade|Downgrade|Erase|Remove|Reinstall|Obsolet)' \
  "${history_tmp}"; then
  die 'DNF transaction contains non-install action'
fi
for unit in orchestrator redis5 redis7 sentinel5 sentinel7; do
  ! systemctl is-active --quiet "${unit}.service" ||
    die "target unit became active after RPM install: ${unit}"
done
! target_listener_present || die 'target listener appeared after RPM install'

install -o root -g root -m 0600 "${current_tmp}" "${INSTALLED_NEVRA}"
install -o root -g root -m 0600 "${history_tmp}" "${HISTORY_INFO}"
tx_tmp=$(mktemp "${EVIDENCE_DIR}/.q071-dnf-transaction-id.XXXXXX")
printf '%s\n' "${installed_tx}" >"${tx_tmp}"
install -o root -g root -m 0600 "${tx_tmp}" "${TX_FILE}"
rm -f -- "${tx_tmp}"
result_tmp=$(mktemp "${EVIDENCE_DIR}/.q071-install-result.XXXXXX")
{
  printf 'install_result=PASS_RPM_INSTALLED\n'
  printf 'run_id=%s\n' "${RUN_ID}"
  printf 'dnf_transaction_id=%s\n' "${installed_tx}"
  printf 'rpm_manifest_sha256=%s\n' "${EXPECTED_MANIFEST_SHA256}"
  printf 'target_units=INACTIVE\n'
  printf 'target_listeners=NONE\n'
} >"${result_tmp}"
install -o root -g root -m 0600 "${result_tmp}" "${INSTALL_RESULT}"
rm -f -- "${result_tmp}"
mutation_committed=1
trap - ERR
cleanup

printf 'Q071_RPM_INSTALL=PASS_RPM_INSTALLED\n'
printf 'DNF_TRANSACTION_ID=%s\n' "${installed_tx}"
cat "${INSTALLED_NEVRA}"
printf 'TARGET_UNITS=INACTIVE\n'
printf 'TARGET_LISTENERS=NONE\n'
