#!/usr/bin/env bash
# ---------------------------------------------------------------------------
# Storm family-recovery via iddrop — end-to-end demo
# ---------------------------------------------------------------------------
#
# Scenario:
#   Storm's old device is lost / wiped. Papa (Jasper) needs to grant Storm
#   a fresh sub-identity bundle for `storm.vandemeent.aint` on a new device
#   without re-onboarding to AINS from scratch.
#
# Flow (= iddrop offer-first, family-bound):
#   1. Papa generates a fresh sub-identity keypair for Storm
#   2. Papa seals the sub-identity bundle to Storm's NEW device pubkey
#      with TBZ v2 (--type identity)
#   3. Papa drops the sealed envelope in Storm's iddrop inbox
#   4. Storm pulls + unseals on the new device
#   5. Storm registers the sub-identity pubkey under storm.vandemeent.aint
#      → recovered, family-bound, AINS-resolvable
#
# Spec ref: draft-vandemeent-iddrop-00 §6 (offer-first), §8.1-§8.6 validation
# ---------------------------------------------------------------------------

set -eu

TIBETZIP="${TIBETZIP:-/root/.cargo/bin/tibet-zip}"
IDDROP="${IDDROP:-/srv/jtel-stack/packages/tibet-iddrop/target/release/iddrop}"
URL="${TBZ_IDDROP_URL:-http://localhost:8000}"

WORKDIR="$(mktemp -d -t storm-recovery-XXXX)"
cd "$WORKDIR"

banner() {
  echo ""
  echo "════════════════════════════════════════════════════════════════"
  echo "  $1"
  echo "════════════════════════════════════════════════════════════════"
}

banner "0. Setup — fresh keypairs for Papa + Storm's new device"
$TIBETZIP keygen -o papa            2>&1 | tail -1
$TIBETZIP keygen -o storm_newdevice 2>&1 | tail -1
PAPA_PUB=$(cat papa.pub)
STORM_NEW_PUB=$(cat storm_newdevice.pub)
echo ""
echo "  Papa pubkey:          ${PAPA_PUB:0:32}…"
echo "  Storm-newdevice pub:  ${STORM_NEW_PUB:0:32}…"

banner "1. Papa generates a fresh storm.vandemeent.aint sub-identity"
$TIBETZIP keygen -o storm_grant 2>&1 | tail -1
STORM_GRANT_PUB=$(cat storm_grant.pub)
echo ""
echo "  storm.vandemeent.aint pubkey: ${STORM_GRANT_PUB:0:32}…"

banner "2. Build the sub-identity payload (= Storm's new aint material)"
mkdir storm_payload
cat > storm_payload/identity.json << EOF
{
  "claimed_aint": "storm.vandemeent.aint",
  "verifying_key": "${STORM_GRANT_PUB}",
  "private_key_file": "see-storm_grant.priv-in-bundle",
  "issued_by": "jasper.vandemeent.aint",
  "issued_by_pubkey": "${PAPA_PUB}",
  "claim_type": "sub_identity",
  "purpose": "family-recovery: replace lost device under family koepel",
  "valid_from": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
  "expires_at": "$(date -u -d '+90 days' +%Y-%m-%dT%H:%M:%SZ)"
}
EOF
cp storm_grant.priv storm_payload/
cp storm_grant.pub  storm_payload/
ls -la storm_payload/

banner "3. Papa seals the payload for Storm's NEW device pubkey"
$TIBETZIP pack storm_payload/ -o storm-recovery.aint \
  --seal --to "$STORM_NEW_PUB" --from papa.priv --type identity 2>&1 | \
  grep -E "Payload class|Sender|Receiver|Sealed|Format"
echo ""
ls -la storm-recovery.aint
echo "  sha256: $(sha256sum storm-recovery.aint | awk '{print $1}')"

banner "4. Drop in Storm's iddrop inbox (offer-first)"
$IDDROP send --to storm.vandemeent --url "$URL" storm-recovery.aint 2>&1
echo ""
echo "  Peek inbox:"
curl -s "$URL/api/iddrop/inbox/storm.vandemeent/peek" | python3 -m json.tool

banner "5. Storm pulls on NEW device"
$IDDROP pull --as storm.vandemeent --url "$URL" --output ./incoming.aint 2>&1
echo ""
echo "  Byte-identical to what Papa sent?"
ORIG=$(sha256sum storm-recovery.aint | awk '{print $1}')
PULL=$(sha256sum incoming.aint | awk '{print $1}')
[ "$ORIG" = "$PULL" ] && echo "  ✓ identical: $ORIG" || echo "  ✗ MISMATCH"

banner "6. Storm unseals with new-device key"
mkdir materialised
$TIBETZIP unpack incoming.aint -o materialised/ --as storm_newdevice.priv 2>&1 | \
  grep -E "Sender|Receiver|class|✓|Extracted"
echo ""
echo "  Materialised content:"
ls -la materialised/
echo ""
echo "  Identity claim:"
cat materialised/identity.json | python3 -m json.tool

banner "7. (Bonus) Wrong device can't open it"
$TIBETZIP keygen -o some_attacker 2>&1 | tail -1
mkdir attacker_attempt
if $TIBETZIP unpack incoming.aint -o attacker_attempt/ --as some_attacker.priv 2>&1 | grep -q "AEAD"; then
  echo "  ✓ correctly REJECTED — attacker cannot decrypt"
else
  echo "  ✗ FAILED — attacker got in"
fi

banner "✓ Storm family-recovery demo complete"
echo ""
echo "  Workdir: $WORKDIR"
echo ""
echo "  What just happened:"
echo "    L1: TBZ v2 sealed envelope (AES-256-GCM + Ed25519)"
echo "    L2: PayloadClass::Identity declared on the wire"
echo "    L3: iddrop wire transport via brain-api inbox"
echo "    + identity-bound: only Storm's new device can open"
echo "    + provenance: signed by Papa, claim_type = sub_identity"
echo "    + AINS-bound: storm.vandemeent.aint under vandemeent.aint koepel"
