#!/usr/bin/env bash
# 05-build-scanner-image.sh — run on the CONNECTED builder after 00-download.sh
# (it needs no network itself: the build runs with --network=none).
#
# Stages build/context from downloads/ + build/db/, builds
#   localhost/devsecops/drone-scanners:<data date>
# exports it to images/drone-scanners-<data date>-amd64.tar, records the result
# in config/scanner-image.env and runs the offline smoke test (--network=none).
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
source "$ROOT/config/versions.env"

log() { printf '[%s] %s\n' "$(date -u +%H:%M:%SZ)" "$*"; }
die() { printf 'ERROR: %s\n' "$*" >&2; exit 1; }

DB="$ROOT/build/db"
for f in grype/6/vulnerability.db trivy/db/metadata.json trivy/java-db/metadata.json trivy/policy/metadata.json; do
  [[ -s "$DB/$f" ]] || die "build/db/$f missing — run scripts/00-download.sh first"
done
ls "$ROOT"/downloads/rpms/*.rpm >/dev/null 2>&1 || die "downloads/rpms is empty — run scripts/00-download.sh"

# Base image: load the pinned archive if podman does not have it yet.
if ! podman image exists "$UBI_IMAGE_LOCAL"; then
  log "loading base image from images/ubi9-minimal-amd64.tar"
  podman load -q -i "$ROOT/images/ubi9-minimal-amd64.tar"
fi
expected_id="$(awk -F'\t' '$1=="ubi9-minimal" {print $5}' "$ROOT/metadata/images.tsv")"
actual_id="$(podman image inspect --format '{{.Id}}' "$UBI_IMAGE_LOCAL")"
[[ "sha256:${actual_id#sha256:}" == "$expected_id" ]] \
  || die "$UBI_IMAGE_LOCAL has image ID $actual_id, expected $expected_id"

# ---------------------------------------------------------------------------
# Stage the build context. Hard links keep the multi-GB DBs from being copied.
# ---------------------------------------------------------------------------
CTX="$ROOT/build/context"
rm -rf "$CTX"; mkdir -p "$CTX/bin" "$CTX/etc" "$CTX/db" "$CTX/rpms"
for spec in "syft_${SYFT_VERSION}_linux_amd64.tar.gz:syft:$SYFT_SHA256" \
            "grype_${GRYPE_VERSION}_linux_amd64.tar.gz:grype:$GRYPE_SHA256" \
            "trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz:trivy:$TRIVY_SHA256"; do
  IFS=: read -r tgz bin sha <<<"$spec"
  echo "$sha  $ROOT/downloads/$tgz" | sha256sum --check --status || die "$tgz failed checksum"
  tar -xzf "$ROOT/downloads/$tgz" -C "$CTX/bin" "$bin"
done
install -m 0755 "$ROOT/containers/drone-scan" "$CTX/bin/drone-scan"
cp "$ROOT"/config/scanners/{syft.yaml,grype.yaml,trivy.yaml,trivyignore} "$CTX/etc/"
cp "$ROOT"/downloads/rpms/*.rpm "$CTX/rpms/"
(cd "$ROOT/downloads/rpms" && sha256sum --check --quiet "$ROOT/metadata/rpms.sha256")
cp -al "$DB/grype" "$CTX/db/grype"
cp -al "$DB/trivy" "$CTX/db/trivy"
rm -rf "$CTX/db/trivy/fanal"

GRYPE_DB_BUILT="$(jq -r .built "$ROOT/metadata/grype-db-status.json")"
TRIVY_DB_UPDATED="$(jq -r .UpdatedAt "$DB/trivy/db/metadata.json")"
DATA_DATE="$(date -u -d "$GRYPE_DB_BUILT" +%Y%m%d)"
TAG="${SCANNER_IMAGE_TAG:-$DATA_DATE}"
IMAGE="$SCANNER_IMAGE_REPO:$TAG"

log "building $IMAGE (network disabled)"
podman build --pull=never --network=none \
  --build-arg BASE_IMAGE="$UBI_IMAGE_LOCAL" \
  --build-arg SYFT_VERSION="$SYFT_VERSION" \
  --build-arg GRYPE_VERSION="$GRYPE_VERSION" \
  --build-arg TRIVY_VERSION="$TRIVY_VERSION" \
  --build-arg DATA_DATE="$DATA_DATE" \
  --build-arg GRYPE_DB_BUILT="$GRYPE_DB_BUILT" \
  --build-arg TRIVY_DB_UPDATED="$TRIVY_DB_UPDATED" \
  --build-arg MAX_DB_AGE_DAYS="$MAX_DB_AGE_DAYS" \
  -f "$ROOT/containers/Containerfile.scanners" -t "$IMAGE" "$CTX"

log "offline smoke test (--network=none)"
podman run --rm --pull=never --network=none "$IMAGE" drone-scan smoke \
  | tee "$ROOT/metadata/scanner-smoke-test.log" | tail -n 3
grep -q 'SMOKE TEST: PASS' "$ROOT/metadata/scanner-smoke-test.log" || die "smoke test failed"

# ---------------------------------------------------------------------------
# Export + record. Older scanner archives are removed: only one data set ships.
# ---------------------------------------------------------------------------
TAR="images/drone-scanners-${TAG}-amd64.tar"
find "$ROOT/images" -maxdepth 1 -name 'drone-scanners-*-amd64.tar' ! -name "$(basename "$TAR")" -delete
log "exporting $TAR"
rm -f "$ROOT/$TAR"
podman save --format docker-archive -o "$ROOT/$TAR" "$IMAGE"
(cd "$ROOT" && sha256sum "$TAR") > "$ROOT/metadata/drone-scanners-image.sha256"

IMAGE_ID="$(podman image inspect --format '{{.Id}}' "$IMAGE")"
cat > "$ROOT/config/scanner-image.env" <<EOF
# Written by scripts/05-build-scanner-image.sh — do not edit by hand.
SCANNER_IMAGE=$IMAGE
SCANNER_IMAGE_ARCHIVE=$TAR
SCANNER_IMAGE_ID=sha256:${IMAGE_ID#sha256:}
SCANNER_DATA_DATE=$DATA_DATE
GRYPE_DB_BUILT=$GRYPE_DB_BUILT
TRIVY_DB_UPDATED=$TRIVY_DB_UPDATED
EOF
podman image inspect "$IMAGE" > "$ROOT/metadata/drone-scanners-image-inspect.json"
log "built $IMAGE ($(du -h "$ROOT/$TAR" | cut -f1)) — next: scripts/99-package.sh"
