#!/usr/bin/env bash
set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
BIN="${BIN:-"$ROOT/target/debug/quantum-sign"}"

if [[ ! -x "$BIN" ]]; then
  if [[ -x "$ROOT/target/debug/qs-cli" ]]; then
    BIN="$ROOT/target/debug/qs-cli"
  fi
fi

info() { printf '== %s\n' "$1"; }

build() {
  cargo build -q --workspace
}

mkpol() {
  local path="$1" dig="$2"
  cat >"$path" <<JSON
{
  "default_alg": "mldsa-87",
  "allow_algs": ["mldsa-87"],
  "required_signatures": {"m": 2, "n": 2},
  "offline_ok": true,
  "require_fips_only": true,
  "require_level5": true,
  "digest_alg": "$dig",
  "allow_lower_levels": false
}
JSON
}

flow() {
  local dig="$1"
  info "L5 flow ($dig)"
  rm -rf "$ROOT/e2e"
  mkdir -p "$ROOT/e2e/dist" "$ROOT/e2e/keys" "$ROOT/e2e/fragments" "$ROOT/e2e/trust"
  printf 'hello quantum-sign level5\n' >"$ROOT/e2e/dist/app.bin"
  mkpol "$ROOT/e2e/policy.json" "$dig"

  "$BIN" keygen --profile mldsa-87 --secret "$ROOT/e2e/keys/alice.sk" --public "$ROOT/e2e/keys/alice.pub" >/dev/null
  "$BIN" keygen --profile mldsa-87 --secret "$ROOT/e2e/keys/bob.sk" --public "$ROOT/e2e/keys/bob.pub" >/dev/null

  "$BIN" trust import --public "$ROOT/e2e/keys/alice.pub" --trustdb "$ROOT/e2e/trust"
  "$BIN" trust import --public "$ROOT/e2e/keys/bob.pub" --trustdb "$ROOT/e2e/trust"

  "$BIN" quorum init \
    --artifact "$ROOT/e2e/dist/app.bin" \
    --digest "$dig" \
    --policy "$ROOT/e2e/policy.json" \
    --intent "$ROOT/e2e/dist/app.qsi"

  "$BIN" quorum cosign \
    --intent "$ROOT/e2e/dist/app.qsi" \
    --secret "$ROOT/e2e/keys/alice.sk" \
    --public "$ROOT/e2e/keys/alice.pub" \
    --fragment "$ROOT/e2e/fragments/alice.csf" \
    --append "$ROOT/e2e/dist/app.qsig.part"

  "$BIN" quorum cosign \
    --intent "$ROOT/e2e/dist/app.qsi" \
    --secret "$ROOT/e2e/keys/bob.sk" \
    --public "$ROOT/e2e/keys/bob.pub" \
    --fragment "$ROOT/e2e/fragments/bob.csf" \
    --append "$ROOT/e2e/dist/app.qsig.part"

  "$BIN" quorum seal \
    --part "$ROOT/e2e/dist/app.qsig.part" \
    --out "$ROOT/e2e/dist/app.${dig}.qsig" \
    --trust-dir "$ROOT/e2e/trust"

  "$BIN" verify \
    --inp "$ROOT/e2e/dist/app.bin" \
    --sig "$ROOT/e2e/dist/app.${dig}.qsig" \
    --trustdb "$ROOT/e2e/trust"

  "$BIN" verify \
    --inp "$ROOT/e2e/dist/app.bin" \
    --sig "$ROOT/e2e/dist/app.${dig}.qsig" \
    --trustdb "$ROOT/e2e/trust" \
    --json >"$ROOT/e2e/dist/app.${dig}.verify.json"

  python3 - "$ROOT/e2e/dist/app.${dig}.verify.json" "$dig" <<'PY'
import json
import sys

path, expected = sys.argv[1:]
with open(path, 'r', encoding='utf-8') as fh:
    data = json.load(fh)
assert data["status"] == "ok", data
assert data["alg"] == "mldsa-87", data
assert data["digest_alg"] == expected, data
assert data["domain"] == "quantum-sign-v1", data
assert data["canonical"] is True, data
assert data["kids_verified"] == 2, data
assert len(data["verified_kids"]) == 2, data
assert data["qsig_size"] > 0, data
print("json verify ok")
PY
}

negs() {
  info "Negative guardrails"

  if "$BIN" quorum init --artifact "$ROOT/e2e/dist/app.bin" --digest sha256 \
    --policy "$ROOT/e2e/policy.json" --intent "$ROOT/e2e/dist/bad.qsi"; then
    echo "expected sha256 rejection" >&2
    return 1
  fi

  local bad
  bad="$(ls "$ROOT"/e2e/trust/*.spki | head -n1)"
  mv "$bad" "${bad%.spki}.mismatch.spki"
  if "$BIN" quorum seal --part "$ROOT/e2e/dist/app.qsig.part" \
    --out "$ROOT/e2e/dist/should_fail.qsig" \
    --trust-dir "$ROOT/e2e/trust"; then
    echo "expected KID mismatch rejection" >&2
    return 1
  fi
}

main() {
  cd "$ROOT"
  build
  flow sha512
  flow shake256-64
  negs
  info "OK: L5 flows + guardrails"
}

main "$@"
