#!/usr/bin/env bash
# quantumunix-fetch-iso.sh
# Download a QuantumUnix ISO release artifact and verify its checksum + signature
# before handing it back to the user. Refuses to keep an unverified ISO.
#
# Author: Dr. Sarunas Grigaliunas
# License: MIT

set -Eeuo pipefail

REPO="quantumunix/quantumunix"
RELEASE="${RELEASE:-latest}"
ARTIFACT="${ARTIFACT:-quantumunix-workstation-x86_64.iso}"
OUT_DIR="${OUT_DIR:-${PWD}}"

log() { printf '[qu] %s\n' "$*" >&2; }
die() { printf '[qu:error] %s\n' "$*" >&2; exit 1; }

usage() {
  cat <<USAGE
Usage:
  $0 [--release TAG] [--artifact NAME] [--out DIR]

Defaults:
  --release   ${RELEASE}
  --artifact  ${ARTIFACT}
  --out       ${OUT_DIR}

Downloads:
  <ARTIFACT>
  <ARTIFACT>.sha256
  <ARTIFACT>.sig          (cosign signature, optional)
  <ARTIFACT>.pem          (cosign certificate, optional)

Verifies SHA-256 strictly. If cosign is installed and the .sig + .pem are
present, verifies the cosign signature too. Anything else is fatal.
USAGE
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    --release)  RELEASE="$2"; shift 2 ;;
    --artifact) ARTIFACT="$2"; shift 2 ;;
    --out)      OUT_DIR="$2"; shift 2 ;;
    -h|--help)  usage; exit 0 ;;
    *)          die "unknown argument: $1" ;;
  esac
done

command -v curl    >/dev/null || die "curl is required"
command -v sha256sum >/dev/null || die "sha256sum is required"

mkdir -p "${OUT_DIR}"
cd "${OUT_DIR}"

if [[ "${RELEASE}" == "latest" ]]; then
  BASE="https://github.com/${REPO}/releases/latest/download"
else
  BASE="https://github.com/${REPO}/releases/download/${RELEASE}"
fi

fetch() {
  local file="$1" required="$2"
  log "downloading ${file}..."
  if ! curl -fL --proto '=https' --tlsv1.2 -o "${file}" "${BASE}/${file}"; then
    if [[ "${required}" == "yes" ]]; then
      die "failed to download required artifact: ${file}"
    fi
    log "optional artifact missing: ${file} (continuing)"
    return 1
  fi
}

fetch "${ARTIFACT}"          yes
fetch "${ARTIFACT}.sha256"   yes
fetch "${ARTIFACT}.sig"      no || true
fetch "${ARTIFACT}.pem"      no || true

log "verifying SHA-256..."
sha256sum -c "${ARTIFACT}.sha256" \
  || { rm -f "${ARTIFACT}"; die "SHA-256 mismatch — file removed for safety"; }

if command -v cosign >/dev/null && [[ -f "${ARTIFACT}.sig" && -f "${ARTIFACT}.pem" ]]; then
  log "verifying cosign signature..."
  cosign verify-blob \
    --certificate "${ARTIFACT}.pem" \
    --signature   "${ARTIFACT}.sig" \
    --certificate-identity-regexp '.*' \
    --certificate-oidc-issuer-regexp '.*' \
    "${ARTIFACT}" \
    || die "cosign verification failed"
  log "cosign signature OK."
else
  log "cosign not run (binary or .sig/.pem missing). SHA-256 verified only."
fi

log "OK: ${OUT_DIR}/${ARTIFACT}"
