#!/usr/bin/env bash

set -Eeuo pipefail
export LANG=C
umask 077

EXPECTED_HOSTNAME="sqjcmqtt01"
EXPECTED_IPV4="10.2.203.108"
EXPECTED_NEVRA="emqx-5.8.9-1.el8.x86_64"
BUNDLE_ROOT="/opt/zhct-deploy"
RUN_ID=${1:-}
Q080_RUN_ID=${2:-}
CONFIRM=${3:-}
EVIDENCE_DIR="/var/backups/zhct-q081/evidence/${RUN_ID}"
Q080_EVIDENCE="/root/q080-evidence/${Q080_RUN_ID}"
UNITS=(emqx.service mosquitto.service)
TARGET_PORT_RE=':(1883|8083|18083|4370|5370|8883|8084)([[:space:]]|$)'

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

stop_units() {
  for unit in "${UNITS[@]}"; do
    systemctl disable --now "${unit}" >/dev/null 2>&1 || true
  done
}

on_error() {
  local rc=$?
  stop_units
  {
    printf 'run_id=%s\n' "${RUN_ID}"
    printf 'install_execution=FAILED\n'
    printf 'exit_code=%s\n' "${rc}"
    printf 'target_units_forced_inactive=ATTEMPTED\n'
    printf 'rollback_required=YES_IF_DNF_ADVANCED\n'
  } >"${EVIDENCE_DIR}/install-result.env"
  exit "${rc}"
}

[[ "${EUID}" -eq 0 ]] || die "must run as root"
[[ "${RUN_ID}" =~ ^q081-[0-9]{8}T[0-9]{6}[+]0800$ ]] || die "invalid Q081 run id"
[[ "${Q080_RUN_ID}" =~ ^q080-[0-9]{8}T[0-9]{6}[+]0800$ ]] || die "invalid Q080 run id"
[[ "${CONFIRM}" == "--execute-q081-install" ]] || die "explicit Q081 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"
[[ -s "${Q080_EVIDENCE}/q080-result.env" ]] || die "Q080 result is missing"
grep -Fxq 'asset_lock=PASS' "${Q080_EVIDENCE}/q080-result.env" || die "Q080 asset gate is not PASS"
grep -Fxq 'install_execution=NOT_PERFORMED' "${Q080_EVIDENCE}/q080-result.env" || die "Q080 install boundary is invalid"
[[ ! -e "${EVIDENCE_DIR}" ]] || die "Q081 evidence run already exists"
[[ -z "$(ss -lntupH | grep -E "${TARGET_PORT_RE}" || true)" ]] || die "an EMQX target port is occupied"
for unit in "${UNITS[@]}"; do
  systemctl is-active --quiet "${unit}" && die "${unit} is active before installation"
done

install -d -m 0700 "${EVIDENCE_DIR}"
exec 9>/run/lock/zhct-q081-install.lock
flock -n 9 || die "another Q081 installation process is running"
trap on_error ERR
dnf history list >"${EVIDENCE_DIR}/dnf-history-before.txt"
rpm -qa --qf '%{NAME}\t%{EPOCHNUM}:%{VERSION}-%{RELEASE}\t%{ARCH}\n' |
  sort >"${EVIDENCE_DIR}/rpm-before.tsv"
before_id=$(awk '$1 ~ /^[0-9]+$/ {print $1; exit}' "${EVIDENCE_DIR}/dnf-history-before.txt")
before_id=${before_id:-0}
RUN_ID="${RUN_ID}" BACKUP_ROOT="/var/backups/zhct-q081/files" \
  "${BUNDLE_ROOT}/common/scripts/install-role.sh" \
  --role emqx --bundle-root "${BUNDLE_ROOT}" >"${EVIDENCE_DIR}/install-role.log" 2>&1

dnf history list >"${EVIDENCE_DIR}/dnf-history-after.txt"
mapfile -t new_ids < <(awk -v before="${before_id}" '$1 ~ /^[0-9]+$/ && $1 > before {print $1}' \
  "${EVIDENCE_DIR}/dnf-history-after.txt" | sort -n)
[[ "${#new_ids[@]}" -eq 2 ]] || die "expected exactly two new DNF transactions"
closure_tx=${new_ids[0]}
emqx_tx=${new_ids[1]}
dnf history info "${closure_tx}" >"${EVIDENCE_DIR}/dnf-history-closure.txt" 2>&1
dnf history info "${emqx_tx}" >"${EVIDENCE_DIR}/dnf-history-emqx.txt" 2>&1
for history in "${EVIDENCE_DIR}/dnf-history-closure.txt" "${EVIDENCE_DIR}/dnf-history-emqx.txt"; do
  grep -Eiq '^[[:space:]]*(Upgrade|Downgrade|Erase|Remove|Reinstall|Obsolete)[[:space:]]' "${history}" &&
    die "DNF transaction contains a non-install action"
done
grep -Eiq '(^|[[:space:]])mosquitto([-.[:space:]]|$)' "${EVIDENCE_DIR}/dnf-history-closure.txt" ||
  die "closure transaction does not contain mosquitto"
grep -Eiq '(^|[[:space:]])libatomic([-.[:space:]]|$)' "${EVIDENCE_DIR}/dnf-history-closure.txt" ||
  die "closure transaction does not contain libatomic"
grep -Eiq '(^|[[:space:]])emqx([-.[:space:]]|$)' "${EVIDENCE_DIR}/dnf-history-emqx.txt" ||
  die "second transaction does not contain EMQX"
printf '%s\n' "${closure_tx}" >"${EVIDENCE_DIR}/dnf-closure-tx-id.txt"
printf '%s\n' "${emqx_tx}" >"${EVIDENCE_DIR}/dnf-emqx-tx-id.txt"

"${BUNDLE_ROOT}/common/scripts/verify-role.sh" \
  --role emqx --bundle-root "${BUNDLE_ROOT}" >"${EVIDENCE_DIR}/verify-role.txt" 2>&1
[[ "$(rpm -q --qf '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}' emqx)" == "${EXPECTED_NEVRA}" ]] ||
  die "installed EMQX NEVRA mismatch"
command -v mosquitto_pub >"${EVIDENCE_DIR}/mosquitto-pub-path.txt"
command -v mosquitto_sub >"${EVIDENCE_DIR}/mosquitto-sub-path.txt"
ldconfig -p | grep -F 'libatomic.so.1' >"${EVIDENCE_DIR}/libatomic-loader.txt"
ldd "$(command -v mosquitto_pub)" >"${EVIDENCE_DIR}/mosquitto-pub-ldd.txt"
ldd "$(command -v mosquitto_sub)" >"${EVIDENCE_DIR}/mosquitto-sub-ldd.txt"
grep -Fq 'not found' "${EVIDENCE_DIR}/mosquitto-pub-ldd.txt" && die "mosquitto_pub has an unresolved library"
grep -Fq 'not found' "${EVIDENCE_DIR}/mosquitto-sub-ldd.txt" && die "mosquitto_sub has an unresolved library"
stop_units
for unit in "${UNITS[@]}"; do
  enabled=$(systemctl is-enabled "${unit}" 2>/dev/null || true)
  active=$(systemctl is-active "${unit}" 2>/dev/null || true)
  [[ "${enabled}" == "disabled" || "${enabled}" == "masked" ]] || die "${unit} is not disabled"
  [[ "${active}" != "active" && "${active}" != "activating" ]] || die "${unit} is active"
done
[[ -z "$(ss -lntupH | grep -E "${TARGET_PORT_RE}" || true)" ]] || die "an EMQX target listener remains"
rpm -qa --qf '%{NAME}\t%{EPOCHNUM}:%{VERSION}-%{RELEASE}\t%{ARCH}\n' |
  sort >"${EVIDENCE_DIR}/rpm-after.tsv"
comm -13 "${EVIDENCE_DIR}/rpm-before.tsv" "${EVIDENCE_DIR}/rpm-after.tsv" >"${EVIDENCE_DIR}/rpm-added.tsv"

{
  printf 'run_id=%s\n' "${RUN_ID}"
  printf 'q080_run_id=%s\n' "${Q080_RUN_ID}"
  printf 'dnf_history_id_before=%s\n' "${before_id}"
  printf 'dnf_closure_tx_id=%s\n' "${closure_tx}"
  printf 'dnf_emqx_tx_id=%s\n' "${emqx_tx}"
  printf 'dnf_transaction_count=2\n'
  printf 'dnf_actions=INSTALL_ONLY\n'
  printf 'static_verify=PASS\n'
  printf 'target_units_disabled_inactive=PASS\n'
  printf 'target_listener_count=0\n'
  printf 'install_execution=PASS\n'
  printf 'loopback_pubsub=NOT_PERFORMED\n'
  printf 'rollback_required=NO\n'
} >"${EVIDENCE_DIR}/install-result.env"
trap - ERR
chmod -R go-rwx "${EVIDENCE_DIR}"
printf 'EMQX01_Q081_INSTALL_STATIC_OK\n'
cat "${EVIDENCE_DIR}/install-result.env"
