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

EXPECTED_HOSTNAME=sqjcredis01
EXPECTED_IPV4=10.2.203.112
RUN_ID=${1:-}
CONFIRM=${2:-}
EVIDENCE_DIR="/var/backups/zhct-q070/evidence/${RUN_ID}"
FILES_DIR="/var/backups/zhct-q070/files/${RUN_ID}"
BUNDLE_ROOT=/opt/zhct-deploy

die() { printf 'ERROR: %s\n' "$*" >&2; exit 1; }
was_absent() {
  awk -F'\t' -v expected="$1" '$1 == expected && $2 == "ABSENT" {found=1} END {exit !found}' \
    "${EVIDENCE_DIR}/path-state-before.tsv"
}

[[ "${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-redis01-fresh-install-rollback ]] ||
  die 'explicit rollback 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 "${EVIDENCE_DIR}/baseline-result.env" ]] || die 'baseline result is missing'
[[ -s "${EVIDENCE_DIR}/path-state-before.tsv" ]] || die 'path baseline is missing'
[[ -s "${EVIDENCE_DIR}/account-state-before.tsv" ]] || die 'account baseline is missing'

for unit in redis5 redis7 sentinel5 sentinel7 orchestrator; do
  systemctl disable --now "${unit}.service" >/dev/null 2>&1 || true
done

TX_FILE="${EVIDENCE_DIR}/q071-dnf-transaction-ids.txt"
if [[ -s "${TX_FILE}" ]]; then
  mapfile -t tx_ids <"${TX_FILE}"
  for ((i=${#tx_ids[@]}-1; i>=0; i--)); do
    tx_id=${tx_ids[$i]}
    [[ "${tx_id}" =~ ^[0-9]+$ ]] || die 'invalid DNF transaction id'
    info="${EVIDENCE_DIR}/rollback-dnf-${tx_id}-info.txt"
    dnf history info "${tx_id}" >"${info}" 2>&1
    grep -Fq "${BUNDLE_ROOT}/packages/rpms/" "${info}" ||
      die "DNF transaction ${tx_id} is not from the Redis01 local closure"
    if grep -Eiq '^[[:space:]]*(Upgrade|Downgrade|Erase|Remove|Reinstall|Obsolete)[[:space:]]' "${info}"; then
      die "DNF transaction ${tx_id} is not install-only"
    fi
    dnf history undo -y "${tx_id}" >"${EVIDENCE_DIR}/rollback-dnf-${tx_id}-undo.log" 2>&1
  done
fi

"$(dirname "$0")/redis01-system-params.sh" --rollback "${RUN_ID}"

paths=(
  /opt/redis/5.0.14 /opt/redis/7.2.14 /etc/redis
  /data/redis5 /data/redis7
  /var/lib/redis-sentinel5 /var/lib/redis-sentinel7
  /var/log/redis5 /var/log/redis7
  /var/log/redis-sentinel5 /var/log/redis-sentinel7
  /var/lib/orchestrator /var/log/orchestrator /etc/orchestrator.conf.json
  /etc/zhct/templates/redis
  /etc/systemd/system/redis5.service /etc/systemd/system/redis7.service
  /etc/systemd/system/sentinel5.service /etc/systemd/system/sentinel7.service
)
for path in "${paths[@]}"; do
  if was_absent "${path}"; then
    rm -rf "${path}"
  else
    source_path="${FILES_DIR}/${path#/}"
    [[ -e "${source_path}" || -L "${source_path}" ]] || die "backup missing: ${path}"
    rm -rf "${path}"
    install -d -m 0700 "$(dirname "${path}")"
    cp -a "${source_path}" "${path}"
  fi
done

for account in redis orchestrator; do
  if awk -F'\t' -v expected="${account}" \
    '$1 == expected && $2 == "ABSENT" {found=1} END {exit !found}' \
    "${EVIDENCE_DIR}/account-state-before.tsv"; then
    userdel "${account}" >/dev/null 2>&1 || true
    groupdel "${account}" >/dev/null 2>&1 || true
  fi
done

systemctl daemon-reload
for unit in redis5 redis7 sentinel5 sentinel7 orchestrator; do
  systemctl is-active --quiet "${unit}.service" && die "unit remains active: ${unit}"
done
for port in 6379 6387 26379 26387 3000 10008; do
  ss -H -lnt "sport = :${port}" | grep -q . && die "target port remains listening: ${port}"
done
printf 'REDIS01_FRESH_INSTALL_ROLLBACK_OK\n'
