#!/usr/bin/env bash
# Import a Grype DB archive into ./cache. Needs no network: run it on the
# air-gapped host after extracting grype-db-offline-YYYYMMDD.tar.gz.
#
#   ./import-db.sh                                   # the archive in ./archive
#   ./import-db.sh /path/vulnerability-db_v6...tar.zst
set -euo pipefail

ROOT="$(cd "$(dirname "$0")" && pwd)"
GRYPE="${GRYPE:-$ROOT/bin/grype}"

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

archive="${1:-}"
if [[ -z "$archive" ]]; then
  shopt -s nullglob; found=("$ROOT"/archive/vulnerability-db_*.tar.zst); shopt -u nullglob
  [[ ${#found[@]} -eq 1 ]] || die "expected exactly one archive in $ROOT/archive (found ${#found[@]}); pass the path"
  archive="${found[0]}"
fi
[[ -f "$archive" ]] || die "no such file: $archive"

# Verify against the listing saved at download time, when it names this archive.
if [[ -s "$ROOT/metadata/latest.json" ]] && [[ "$(jq -r .path "$ROOT/metadata/latest.json")" == "$(basename "$archive")" ]]; then
  sha="$(jq -r '.checksum | sub("^sha256:";"")' "$ROOT/metadata/latest.json")"
  echo "$sha  $archive" | sha256sum --check --status || die "checksum mismatch: $archive"
  log "checksum ok $(basename "$archive")"
else
  log "WARN: no saved listing for $(basename "$archive"), skipping checksum check"
fi

# Import into a staging dir so a failed import never breaks the working cache.
export GRYPE_CHECK_FOR_APP_UPDATE=false GRYPE_DB_AUTO_UPDATE=false GRYPE_DB_VALIDATE_AGE=false
STAGE="$ROOT/cache.new"
rm -rf "$STAGE"; mkdir -p "$STAGE"
log "importing into cache/"
GRYPE_DB_CACHE_DIR="$STAGE" "$GRYPE" db import "$archive"
status="$(GRYPE_DB_CACHE_DIR="$STAGE" "$GRYPE" db status -o json)" || true
[[ "$(jq -r .valid <<<"$status")" == true ]] || die "imported DB is not valid: $(jq -r .error <<<"$status")"
rm -rf "$ROOT/cache"; mv "$STAGE" "$ROOT/cache"

{
  echo "imported_utc=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
  echo "grype_version=$("$GRYPE" version | awk '/^Version/{print $2}')"
  echo "db_schema=$(jq -r .schemaVersion <<<"$status")"
  echo "db_built=$(jq -r .built <<<"$status")"
  echo "db_archive=$(basename "$archive")"
} > "$ROOT/DB-VERSION.txt"
cat "$ROOT/DB-VERSION.txt"
