#!/usr/bin/env bash

set -Eeuo pipefail
export LANG=C
umask 077

EXPECTED_HOSTNAME="sqjcDB01"
EXPECTED_IPV4="10.2.208.106"
EXPECTED_OS="openEuler release 24.03 (LTS-SP1)"
EXPECTED_ARCH="x86_64"
BACKUP_ROOT="/var/backups/zhct-q060"
BUNDLE_ROOT="/opt/zhct-deploy"
PACKAGE_ROOT="${BUNDLE_ROOT}/packages"
RPM_ROOT="${PACKAGE_ROOT}/rpms"
STAGE="${PACKAGE_ROOT}/.q060-rpm-stage"
MIN_FINAL_FREE_BYTES=$((9 * 1024 * 1024 * 1024))
ROOT_PACKAGES=(
  libaio
  ncurses-compat-libs
  socat
  tar
  gzip
  xz
  gnupg2
)

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

require_command() {
  command -v "$1" >/dev/null 2>&1 || die "required command not found: $1"
}

reject_non_install_actions() {
  local log_file="$1"
  if grep -Eiq \
    '(^|[[:space:]])(Upgrading|Downgrading|Removing|Reinstalling|Obsoleting)(:|[[:space:]])|^[[:space:]]*(Upgrade|Downgrade|Remove|Reinstall|Obsolete)[[:space:]]+[0-9]+' \
    "${log_file}"; then
    die "DNF plan includes a non-install action: ${log_file}"
  fi
}

[[ "${EUID}" -eq 0 ]] || die "must run as root"
[[ $# -eq 1 ]] || die "usage: $0 <q060-baseline-run-id>"
RUN_ID="$1"
[[ "${RUN_ID}" =~ ^[0-9]{8}T[0-9]{6}[+-][0-9]{4}$ ]] || die "invalid run id"
EVIDENCE_DIR="${BACKUP_ROOT}/${RUN_ID}"
SOURCE_RESULT="${EVIDENCE_DIR}/source-assets-result.env"
FRESH_ROOT="${EVIDENCE_DIR}/fresh-installroot"

for command_name in dnf rpm sha256sum findmnt awk grep sort; do
  require_command "${command_name}"
done
dnf download --help >/dev/null 2>&1 || die "dnf download plugin is unavailable"
[[ "$(hostname -s)" == "${EXPECTED_HOSTNAME}" ]] || die "hostname mismatch"
[[ "$(uname -m)" == "${EXPECTED_ARCH}" ]] || die "architecture 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"
[[ -s "${SOURCE_RESULT}" ]] || die "source asset result is missing"
grep -Fxq 'source_asset_download=PASS' "${SOURCE_RESULT}" || \
  die "source asset gate is not PASS"
grep -Fxq 'install_execution=NOT_PERFORMED' "${SOURCE_RESULT}" || \
  die "source asset phase records an installation"
[[ ! -e "${RPM_ROOT}" ]] || die "final RPM closure already exists: ${RPM_ROOT}"
[[ ! -e "${STAGE}" ]] || die "RPM stage already exists: ${STAGE}"
[[ ! -e "${FRESH_ROOT}" ]] || die "fresh installroot already exists: ${FRESH_ROOT}"

install -d -m 0700 "${STAGE}" "${FRESH_ROOT}"
dnf -v repolist --all >"${EVIDENCE_DIR}/dnf-repolist.txt" 2>&1
find /etc/yum.repos.d -type f -print0 | sort -z |
  xargs -0 -r sha256sum >"${EVIDENCE_DIR}/yum-repo-files.sha256"
find /etc/pki/rpm-gpg -type f -print0 | sort -z |
  xargs -0 -r sha256sum >"${EVIDENCE_DIR}/rpm-gpg-keys.sha256"
find /var/cache/dnf -type f -path '*/repodata/repomd.xml' -print0 | sort -z |
  xargs -0 -r sha256sum >"${EVIDENCE_DIR}/dnf-repomd-sha256.txt"

dnf download --resolve --alldeps \
  --setopt=install_weak_deps=False \
  --destdir "${STAGE}" \
  "${ROOT_PACKAGES[@]}" >"${EVIDENCE_DIR}/dnf-download-alldeps.log" 2>&1
RPM_COUNT="$(find "${STAGE}" -maxdepth 1 -type f -name '*.rpm' | wc -l)"
[[ "${RPM_COUNT}" -gt 0 ]] || die "DNF did not download any RPM"

find "${STAGE}" -maxdepth 1 -type f -name '*.rpm' -print0 | sort -z |
  xargs -0 -r rpm --define '_pkgverify_level signature' -K \
  >"${EVIDENCE_DIR}/rpm-signatures.txt" 2>&1
[[ "$(grep -Ec 'signatures OK$' "${EVIDENCE_DIR}/rpm-signatures.txt")" -eq \
  "${RPM_COUNT}" ]] || die "not every RPM has a trusted signature"
grep -Eiq 'BAD|NOT OK|NOKEY|NOTTRUSTED' "${EVIDENCE_DIR}/rpm-signatures.txt" &&
  die "an RPM signature is not trusted"

find "${STAGE}" -maxdepth 1 -type f -name '*.rpm' -print0 | sort -z |
  xargs -0 -r rpm -qp \
  --qf '%{NAME}\t%{EPOCHNUM}:%{VERSION}-%{RELEASE}\t%{ARCH}\t%{SIZE}\t%{VENDOR}\n' \
  2>/dev/null | sort -u >"${EVIDENCE_DIR}/rpm-nevra.tsv"
awk -F'\t' '{key=$1 FS $3; count[key]++} END {for (key in count) if (count[key] > 1) exit 1}' \
  "${EVIDENCE_DIR}/rpm-nevra.tsv" || die "multiple RPM versions exist for one name/arch"
find "${STAGE}" -maxdepth 1 -type f -name '*.rpm' -print0 | sort -z |
  while IFS= read -r -d '' rpm_file; do
    printf '### %s\n' "$(basename "${rpm_file}")"
    rpm -qpR "${rpm_file}" | sort -u
  done >"${EVIDENCE_DIR}/rpm-requires.txt"

mapfile -d '' closure_rpms < <(
  find "${STAGE}" -maxdepth 1 -type f -name '*.rpm' -print0 | sort -z
)
set +e
dnf --disablerepo='*' \
  --setopt=strict=True \
  --setopt=install_weak_deps=False \
  --assumeno install "${closure_rpms[@]}" \
  >"${EVIDENCE_DIR}/dnf-current-host-assumeno.log" 2>&1
HOST_RC=$?
set -e
[[ "${HOST_RC}" -eq 1 || "${HOST_RC}" -eq 0 ]] || \
  die "unexpected current-host DNF exit code: ${HOST_RC}"
grep -Eiq 'nothing provides|conflicting requests|transaction test error|protected packages' \
  "${EVIDENCE_DIR}/dnf-current-host-assumeno.log" &&
  die "current-host closure has an unresolved dependency or conflict"
reject_non_install_actions "${EVIDENCE_DIR}/dnf-current-host-assumeno.log"

set +e
dnf --installroot="${FRESH_ROOT}" \
  --releasever=24.03_LTS_SP1 \
  --disablerepo='*' \
  --setopt=strict=True \
  --setopt=install_weak_deps=False \
  --setopt=keepcache=False \
  --nogpgcheck \
  --assumeno install "${closure_rpms[@]}" \
  >"${EVIDENCE_DIR}/dnf-fresh-installroot-assumeno.log" 2>&1
FRESH_RC=$?
set -e
[[ "${FRESH_RC}" -eq 1 ]] || die "unexpected fresh-installroot DNF exit code: ${FRESH_RC}"
grep -Fq 'Transaction Summary' "${EVIDENCE_DIR}/dnf-fresh-installroot-assumeno.log" || \
  die "fresh installroot did not reach a transaction summary"
if grep -Eiq 'nothing provides|conflicting requests|transaction test error|protected packages' \
  "${EVIDENCE_DIR}/dnf-fresh-installroot-assumeno.log"; then
  die "fresh-install closure is incomplete; stage and evidence are preserved"
fi
reject_non_install_actions "${EVIDENCE_DIR}/dnf-fresh-installroot-assumeno.log"
rmdir "${FRESH_ROOT}/var/lib/dnf" 2>/dev/null || true
rm -rf "${FRESH_ROOT}"

mv "${STAGE}" "${RPM_ROOT}"
(
  cd "${PACKAGE_ROOT}"
  find rpms -maxdepth 1 -type f -name '*.rpm' -print0 | sort -z |
    xargs -0 sha256sum
) >"${PACKAGE_ROOT}/rpms.sha256"
chmod 0640 "${PACKAGE_ROOT}/rpms.sha256"
chmod -R go-rwx "${RPM_ROOT}"
(
  cd "${PACKAGE_ROOT}"
  sha256sum -c rpms.sha256
) >"${EVIDENCE_DIR}/rpm-sha256-check.txt"

AVAILABLE_AFTER="$(findmnt -bn -o AVAIL /)"
[[ "${AVAILABLE_AFTER}" -ge "${MIN_FINAL_FREE_BYTES}" ]] || \
  die "root free space fell below 9 GiB after closure download"
RPM_MANIFEST_SHA256="$(sha256sum "${PACKAGE_ROOT}/rpms.sha256" | awk '{print $1}')"
{
  printf 'captured_at=%s\n' "$(date --iso-8601=seconds)"
  printf 'rpm_count=%s\n' "${RPM_COUNT}"
  printf 'rpm_bytes=%s\n' "$(du -sb "${RPM_ROOT}" | awk '{print $1}')"
  printf 'rpm_manifest_sha256=%s\n' "${RPM_MANIFEST_SHA256}"
  printf 'rpm_signature_check=PASS\n'
  printf 'current_host_transaction=INSTALL_ONLY_OR_NOTHING_TO_DO\n'
  printf 'fresh_installroot_dependency_resolution=PASS_ASSUMENO\n'
  printf 'installed_package_pruning=NOT_PERFORMED\n'
  printf 'install_execution=NOT_PERFORMED\n'
  printf 'post_clone_execution=NOT_PERFORMED\n'
} >"${EVIDENCE_DIR}/rpm-closure-result.env"
chmod 0600 "${EVIDENCE_DIR}"/dnf-* "${EVIDENCE_DIR}"/rpm-* \
  "${EVIDENCE_DIR}"/yum-repo-files.sha256

printf 'Q060_FRESH_INSTALL_CLOSURE_OK\n'
cat "${EVIDENCE_DIR}/rpm-closure-result.env"
