#!/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}"
UNITS=(nginx.service keepalived.service haproxy.service orchestrator.service sentinel5.service sentinel7.service)

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

was_absent() {
  local path=$1
  awk -F'\t' -v expected="${path}" '$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}" =~ ^q041-[0-9]{8}T[0-9]{6}[+]0800$ ]] || die "invalid Q041 run id"
[[ "${CONFIRM}" == "--execute-q041-rollback" ]] || die "explicit Q041 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}/preinstall-result.env" ]] || die "preinstall result is missing"
[[ -s "${EVIDENCE_DIR}/path-state-before.tsv" ]] || die "path baseline is missing"

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

if [[ -s "${EVIDENCE_DIR}/dnf-history-id-after.txt" ]]; then
  dnf_transaction_id=$(tr -d '[:space:]' <"${EVIDENCE_DIR}/dnf-history-id-after.txt")
  [[ "${dnf_transaction_id}" =~ ^[0-9]+$ ]] || die "invalid DNF transaction id"
  dnf history info "${dnf_transaction_id}" >"${EVIDENCE_DIR}/rollback-dnf-history-info.txt" 2>&1
  grep -Fq '/opt/zhct-deploy/packages/rpms/' "${EVIDENCE_DIR}/rollback-dnf-history-info.txt" || \
    die "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}/rollback-dnf-history-info.txt" || \
      die "DNF transaction does not contain ${package}"
  done
  if grep -Eiq '^[[:space:]]*(Upgrade|Downgrade|Erase|Remove|Reinstall|Obsolete)[[:space:]]' \
    "${EVIDENCE_DIR}/rollback-dnf-history-info.txt"; then
    die "DNF transaction contains a non-install action; manual review is required"
  fi
  dnf history undo -y "${dnf_transaction_id}" >"${EVIDENCE_DIR}/rollback-dnf-undo.log" 2>&1
fi

if [[ -d "/var/backups/zhct-q041/files/${RUN_ID}" ]]; then
  RUN_ID="${RUN_ID}" \
  BACKUP_ROOT="/var/backups/zhct-q041/files" \
  "${BUNDLE_ROOT}/common/bin/role-action.sh" rollback \
    --role nginx \
    --bundle-root "${BUNDLE_ROOT}" \
    --backup-id "${RUN_ID}" \
    >"${EVIDENCE_DIR}/rollback-role.log" 2>&1 || true
fi

paths=(
  /usr/local/nginx
  /usr/local/haproxy
  /usr/local/sbin/keepalived
  /opt/redis/5.0.14
  /opt/redis/7.2.14
  /etc/zhct/templates/nginx
  /usr/local/sbin/check-front-vip.sh
  /usr/local/sbin/check-mqtt-vip.sh
  /usr/local/sbin/check-db-proxy-vip.sh
  /usr/local/sbin/vip-control.sh
  /usr/local/sbin/provision-edge-secrets.sh
  /etc/sysctl.d/99-zhct-edge.conf
  /etc/systemd/system/nginx.service
  /etc/systemd/system/keepalived.service
  /etc/systemd/system/haproxy.service
  /etc/systemd/system/sentinel5.service
  /etc/systemd/system/sentinel7.service
  /usr/lib/systemd/system/orchestrator.service
  /var/log/nginx
  /var/log/haproxy
  /var/log/redis-sentinel5
  /var/log/redis-sentinel7
  /var/lib/redis-sentinel5
  /var/lib/redis-sentinel7
  /var/lib/orchestrator
  /var/log/orchestrator
  /etc/orchestrator.conf.json
  /var/tmp/zhct-build/nginx
)
for path in "${paths[@]}"; do
  if was_absent "${path}"; then
    rm -rf "${path}"
  fi
done

while IFS=$'\t' read -r key value; do
  [[ -n "${key}" ]] || continue
  sysctl -w "${key}=${value}" >/dev/null
done <"${EVIDENCE_DIR}/sysctl-state-before.tsv"

for account in www haproxy 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
{
  printf 'captured_at=%s\n' "$(date --iso-8601=seconds)"
  printf 'run_id=%s\n' "${RUN_ID}"
  printf 'target_units_disabled_inactive=PASS\n'
  printf 'q041_created_paths_removed=PASS\n'
  printf 'sysctl_restored=PASS\n'
  printf 'dnf_transaction_undo=ATTEMPTED_IF_PRESENT\n'
  printf 'rollback_execution=PASS\n'
} >"${EVIDENCE_DIR}/rollback-result.env"
chmod 0600 "${EVIDENCE_DIR}"/*
printf 'Q041_ROLLBACK_OK\n'
cat "${EVIDENCE_DIR}/rollback-result.env"
