#!/usr/bin/env bash

set -Eeuo pipefail

EXPECTED_HOSTNAME="sqjcnginx01"
EXPECTED_IPV4="10.2.203.102"
EXPECTED_OS="openEuler release 24.03 (LTS-SP1)"
PACKAGE_ROOT="/opt/zhct-deploy/packages"
RPM_ROOT="${PACKAGE_ROOT}/rpms"
EVIDENCE_DIR="/var/backups/zhct-q040/20260722T203557+0800"
BASELINE_RPM="${EVIDENCE_DIR}/baseline/rpm-all.txt"
EXPECTED_RPM_COUNT=303

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

[[ "${EUID}" -eq 0 ]] || die "must run as root"
[[ "$(hostname -s)" == "${EXPECTED_HOSTNAME}" ]] || die "hostname mismatch"
[[ "$(tr -d '\r' </etc/openEuler-release)" == "${EXPECTED_OS}" ]] || die "OS mismatch"
ip -o -4 addr show scope global | awk '{print $4}' | cut -d/ -f1 | \
  grep -Fxq "${EXPECTED_IPV4}" || die "expected IPv4 is not configured"
[[ -d "${RPM_ROOT}" ]] || die "RPM closure is missing"
[[ -f "${BASELINE_RPM}" ]] || die "baseline RPM inventory is missing"

umask 077
manifest_temp=$(mktemp "${PACKAGE_ROOT}/.rpms.sha256.XXXXXX")
baseline_sorted=$(mktemp)
current_sorted=$(mktemp)
baseline_nonkey=$(mktemp)
current_nonkey=$(mktemp)
trap 'rm -f "${manifest_temp}" "${baseline_sorted}" "${current_sorted}" "${baseline_nonkey}" "${current_nonkey}"' EXIT

cd "${PACKAGE_ROOT}"
find rpms -maxdepth 1 -type f -name '*.rpm' -print0 | sort -z | \
  xargs -0 sha256sum >"${manifest_temp}"
rpm_count=$(wc -l <"${manifest_temp}")
[[ "${rpm_count}" -eq "${EXPECTED_RPM_COUNT}" ]] || \
  die "expected ${EXPECTED_RPM_COUNT} RPMs, found ${rpm_count}"
sha256sum -c "${manifest_temp}" >"${EVIDENCE_DIR}/rpm-closure-sha256-check.txt"
mv "${manifest_temp}" "${PACKAGE_ROOT}/rpms.sha256"
chmod 0640 "${PACKAGE_ROOT}/rpms.sha256"

sed '/^#/d;/^[[:space:]]*$/d' "${BASELINE_RPM}" | sort -u >"${baseline_sorted}"
rpm -qa --qf '%{NAME}\t%{EPOCHNUM}:%{VERSION}-%{RELEASE}\t%{ARCH}\n' | sort -u >"${current_sorted}"
diff -u "${baseline_sorted}" "${current_sorted}" \
  >"${EVIDENCE_DIR}/rpm-inventory-before-after.diff" || true
grep -v '^gpg-pubkey[[:space:]]' "${baseline_sorted}" >"${baseline_nonkey}"
grep -v '^gpg-pubkey[[:space:]]' "${current_sorted}" >"${current_nonkey}"
cmp -s "${baseline_nonkey}" "${current_nonkey}" || \
  die "non-key RPM inventory changed during Q040"

mapfile -d '' closure_rpms < <(find "${RPM_ROOT}" -maxdepth 1 -type f -name '*.rpm' -print0 | sort -z)
set +e
dnf --disablerepo='*' \
  --setopt=install_weak_deps=False \
  --setopt=localpkg_gpgcheck=False \
  --assumeno install "${closure_rpms[@]}" \
  >"${EVIDENCE_DIR}/dnf-offline-closure-assumeno.log" 2>&1
dnf_rc=$?
set -e
[[ "${dnf_rc}" -eq 1 ]] || die "unexpected DNF assumeno exit code: ${dnf_rc}"
grep -Fq 'Operation aborted.' "${EVIDENCE_DIR}/dnf-offline-closure-assumeno.log" || \
  die "DNF assumeno did not reach an install decision"
if grep -Eiq 'nothing provides|conflicting requests|problem:[[:space:]]|transaction test error' \
  "${EVIDENCE_DIR}/dnf-offline-closure-assumeno.log"; then
  die "offline RPM closure has an unresolved dependency or conflict"
fi

manifest_sha256=$(sha256sum "${PACKAGE_ROOT}/rpms.sha256" | awk '{print $1}')
rpm_bytes=$(du -sb "${RPM_ROOT}" | awk '{print $1}')
normal_rpm_diff_lines=$(grep -Ev '^([-+]{3}|@@|[+-]gpg-pubkey)' \
  "${EVIDENCE_DIR}/rpm-inventory-before-after.diff" | grep -Ec '^[+-]' || true)
{
  printf 'captured_at=%s\n' "$(date --iso-8601=seconds)"
  printf 'rpm_count=%s\n' "${rpm_count}"
  printf 'rpm_bytes=%s\n' "${rpm_bytes}"
  printf 'rpm_manifest_sha256=%s\n' "${manifest_sha256}"
  printf 'rpm_sha256_check=PASS\n'
  printf 'non_key_rpm_inventory_change_count=%s\n' "${normal_rpm_diff_lines}"
  printf 'non_key_rpm_inventory_check=PASS\n'
  printf 'dnf_offline_dependency_resolution=PASS_ASSUMENO\n'
  printf 'install_execution=NOT_PERFORMED\n'
} >"${EVIDENCE_DIR}/rpm-assets-finalize-result.env"

chmod 0600 "${EVIDENCE_DIR}/rpm-closure-sha256-check.txt" \
  "${EVIDENCE_DIR}/rpm-inventory-before-after.diff" \
  "${EVIDENCE_DIR}/dnf-offline-closure-assumeno.log" \
  "${EVIDENCE_DIR}/rpm-assets-finalize-result.env"

printf 'Q040_RPM_ASSETS_FINALIZE_OK\n'
cat "${EVIDENCE_DIR}/rpm-assets-finalize-result.env"
