#!/usr/bin/env bash

set -Eeuo pipefail

EXPECTED_HOSTNAME="sqjcnginx01"
EXPECTED_IPV4="10.2.203.102"
EXPECTED_SOURCE_COMMIT="47584918681b8aad36fee3c9eade5cd919c702ab"
EXPECTED_FRAMEWORK_SHA256="f74941f6328c752eeefb5fe082c4366dfed5c91ecad36d31ba7e11b7d2cac2d5"
EXPECTED_RPM_MANIFEST_SHA256="0ef1b62af801d782e8331b608b4b0580e0721a7553e913ab17686d4dc32dee3d"
BUNDLE_ROOT="/opt/zhct-deploy"
EVIDENCE_DIR="/var/backups/zhct-q040/20260722T203557+0800"
FINAL_EVIDENCE_INDEX="${EVIDENCE_DIR}/q040-final-evidence-index.sha256"
FINAL_STATE_INDEX="${EVIDENCE_DIR}/q040-final-state-index.sha256"
SENSITIVE_SCAN="${EVIDENCE_DIR}/q040-sensitive-scan.txt"
EXCLUSIONS="${EVIDENCE_DIR}/q040-final-evidence-exclusions.txt"

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

[[ "${EUID}" -eq 0 ]] || die "must run as root"
[[ "$(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"
[[ "$(tr -d '\r\n' <"${BUNDLE_ROOT}/.source-commit")" == "${EXPECTED_SOURCE_COMMIT}" ]] || \
  die "source commit marker mismatch"
[[ "$(tr -d '\r\n' <"${BUNDLE_ROOT}/.framework-bundle-sha256")" == "${EXPECTED_FRAMEWORK_SHA256}" ]] || \
  die "framework bundle marker mismatch"
[[ "$(sha256sum "${BUNDLE_ROOT}/packages/rpms.sha256" | awk '{print $1}')" == "${EXPECTED_RPM_MANIFEST_SHA256}" ]] || \
  die "RPM manifest SHA256 mismatch"
[[ $(wc -l <"${BUNDLE_ROOT}/packages/rpms.sha256") -eq 18 ]] || \
  die "RPM manifest does not contain 18 rows"

required_results=(
  result.env
  file-inventory.tsv
  sha256sums.txt
  config/system-config-before-q040.tar.gz
  minimal-rpm-closure-result.env
  framework-47584918-refresh-result.env
  v8-result.env
  post-download-check-result.env
  q040-v8-evidence-index.sha256
  rpm-keyring-before-after.diff
  compatible-rpm-classification.tsv
  dnf-compatible-closure-assumeno.log
  compatible-openeuler-rpm-signatures.txt
  orchestrator-rpm-signature-verified.txt
  percona-packaging-key.txt
  percona-packaging-key.sha256
  nginx-role-install-dry-run.log
)
for required_result in "${required_results[@]}"; do
  [[ -s "${EVIDENCE_DIR}/${required_result}" ]] || die "required evidence is missing: ${required_result}"
done
sha256sum -c "${EVIDENCE_DIR}/sha256sums.txt" \
  >"${EVIDENCE_DIR}/v10-baseline-backup-sha256-check.txt"

grep -Fq 'dnf_transaction_actions=INSTALL_ONLY' \
  "${EVIDENCE_DIR}/post-download-check-result.env" || die "post-download DNF action check is not PASS"
grep -Fq 'target_listener_count=0' "${EVIDENCE_DIR}/post-download-check-result.env" || \
  die "post-download target listener count is not zero"
grep -Fq 'target_process_count=0' "${EVIDENCE_DIR}/post-download-check-result.env" || \
  die "post-download target process count is not zero"
grep -Fq 'target_unit_count=0' "${EVIDENCE_DIR}/post-download-check-result.env" || \
  die "post-download target unit count is not zero"
grep -Fq 'target_rpm_count=0' "${EVIDENCE_DIR}/post-download-check-result.env" || \
  die "post-download target RPM count is not zero"
grep -Fq 'vip_announcement_count=0' "${EVIDENCE_DIR}/post-download-check-result.env" || \
  die "post-download VIP announcement count is not zero"

template_roots=(
  "${BUNDLE_ROOT}/roles/nginx/templates/haproxy"
  "${BUNDLE_ROOT}/roles/nginx/templates/nodes"
)
secret_key_lines=$(grep -RInE \
  'MySQLTopologyPassword|auth-pass|auth_pass|tcp-check[[:space:]]+send[[:space:]]+AUTH' \
  "${template_roots[@]}" || true)
[[ -n "${secret_key_lines}" ]] || die "expected secret placeholder lines are missing"
unresolved_plaintext=$(printf '%s\n' "${secret_key_lines}" | grep -Ev '__[A-Z0-9_]+__' || true)
[[ -z "${unresolved_plaintext}" ]] || die "a secret-bearing template line lacks a placeholder"

private_key_markers=$(grep -RIlE \
  'BEGIN (RSA |EC |OPENSSH )?PRIVATE KEY' \
  "${BUNDLE_ROOT}/common" "${BUNDLE_ROOT}/roles/nginx" || true)
[[ -z "${private_key_markers}" ]] || die "private key material exists in the framework"
credential_urls=$(grep -RInE \
  '://[^/[:space:]:]+:[^/@[:space:]]+@' \
  "${BUNDLE_ROOT}/common" "${BUNDLE_ROOT}/roles/nginx" || true)
[[ -z "${credential_urls}" ]] || die "credential-bearing URL exists in the framework"
[[ ! -e /etc/zhct/secrets ]] || die "runtime secret directory was created during Q040"

{
  printf 'captured_at=%s\n' "$(date --iso-8601=seconds)"
  printf 'template_secret_lines=%s\n' "$(printf '%s\n' "${secret_key_lines}" | wc -l)"
  printf 'template_secret_lines_without_placeholder=0\n'
  printf 'private_key_file_count=0\n'
  printf 'credential_url_count=0\n'
  printf 'runtime_secret_directory=ABSENT\n'
  printf 'sensitive_scan=PASS\n'
} >"${SENSITIVE_SCAN}"

{
  printf '# Excluded binary payload directories are retained under rejected-assets.\n'
  printf '# Their manifests, classification files, DNF logs, signatures and result env files are indexed.\n'
  printf 'rejected-assets/rpms-303/**\n'
  printf 'rejected-assets/rpms-29-upgrades/**\n'
  printf 'rejected-assets/rpms-18-unresolved-exact-deps/**\n'
} >"${EXCLUSIONS}"

evidence_temp=$(mktemp "${EVIDENCE_DIR}/.q040-final-evidence-index.XXXXXX")
state_temp=$(mktemp "${EVIDENCE_DIR}/.q040-final-state-index.XXXXXX")
trap 'rm -f "${evidence_temp}" "${state_temp}"' EXIT
(
  cd "${EVIDENCE_DIR}"
  find . -type f \
    ! -path './rejected-assets/rpms-303/*' \
    ! -path './rejected-assets/rpms-29-upgrades/*' \
    ! -path './rejected-assets/rpms-18-unresolved-exact-deps/*' \
    ! -name 'q040-final-evidence-index.sha256' \
    ! -name 'q040-final-evidence-index.sha256.sha256' \
    ! -name 'q040-final-state-index.sha256' \
    ! -name 'q040-final-state-index.sha256.sha256' \
    ! -name 'v10-result.env' \
    ! -name '.q040-final-evidence-index.*' \
    ! -name '.q040-final-state-index.*' \
    -print0 | sort -z | xargs -0 sha256sum
) >"${evidence_temp}"
[[ -s "${evidence_temp}" ]] || die "final evidence index is empty"
mv "${evidence_temp}" "${FINAL_EVIDENCE_INDEX}"
sha256sum "${FINAL_EVIDENCE_INDEX}" >"${FINAL_EVIDENCE_INDEX}.sha256"

state_files=(
  .source-commit
  .framework-bundle-sha256
  roles/nginx/manifests/asset-digests.tsv
  roles/nginx/manifests/packages.sha256
  roles/nginx/manifests/packages.tsv
  roles/nginx/manifests/repo-snapshot.txt
  packages/rpms.sha256
)
(
  cd "${BUNDLE_ROOT}"
  sha256sum "${state_files[@]}"
) >"${state_temp}"
mv "${state_temp}" "${FINAL_STATE_INDEX}"
sha256sum "${FINAL_STATE_INDEX}" >"${FINAL_STATE_INDEX}.sha256"

evidence_count=$(wc -l <"${FINAL_EVIDENCE_INDEX}")
evidence_index_sha256=$(awk '{print $1}' "${FINAL_EVIDENCE_INDEX}.sha256")
state_count=$(wc -l <"${FINAL_STATE_INDEX}")
state_index_sha256=$(awk '{print $1}' "${FINAL_STATE_INDEX}.sha256")
{
  printf 'captured_at=%s\n' "$(date --iso-8601=seconds)"
  printf 'evidence_file_count=%s\n' "${evidence_count}"
  printf 'evidence_index_sha256=%s\n' "${evidence_index_sha256}"
  printf 'final_state_file_count=%s\n' "${state_count}"
  printf 'final_state_index_sha256=%s\n' "${state_index_sha256}"
  printf 'required_evidence_check=PASS\n'
  printf 'sensitive_scan=PASS\n'
  printf 'backup_entry=PASS\n'
  printf 'rollback_entry=PASS\n'
  printf 'install_execution=NOT_PERFORMED\n'
  printf 'target_service_start=NOT_PERFORMED\n'
  printf 'q041_execution=LOCKED_NOT_STARTED\n'
} >"${EVIDENCE_DIR}/v10-result.env"

chmod 0600 "${FINAL_EVIDENCE_INDEX}" "${FINAL_EVIDENCE_INDEX}.sha256" \
  "${FINAL_STATE_INDEX}" "${FINAL_STATE_INDEX}.sha256" \
  "${SENSITIVE_SCAN}" "${EXCLUSIONS}" "${EVIDENCE_DIR}/v10-result.env"

printf 'Q040_FINAL_AUDIT_CHECK_OK\n'
cat "${EVIDENCE_DIR}/v10-result.env"
