#!/usr/bin/env bash
# zentient-PTO agent-kit — verified installer wrapper
#
# Fetches install.sh + detached Ed25519 signature + pubkey + SHA-256 hash,
# verifies both hash and signature against the PINNED pubkey fingerprint
# below, then executes install.sh. If any check fails, we refuse to execute.
#
# This wrapper is small on purpose. Inspect it before piping to bash:
#   curl -fsSL https://zentient.studio/pto/agent-kit/verify-and-install.sh | cat
#
# Canonical URL:  https://zentient.studio/pto/agent-kit/verify-and-install.sh
# Pinned pubkey SHA-256 fingerprint (DER SubjectPublicKeyInfo):
PINNED_PUBKEY_FPR="f00032a2cba3dbe5836b0fc978e595288e79977af741efaca2748be557710750"

set -euo pipefail

BASE="${ZENTIENT_PTO_KIT_BASE:-https://zentient.studio/pto/agent-kit}"

# ─── require tools ──────────────────────────────────────────────────────
need() { command -v "$1" >/dev/null 2>&1 || { echo "✗ required tool missing: $1" >&2; exit 1; }; }
need curl
need sha256sum 2>/dev/null || need shasum   # linux has sha256sum, macOS has shasum
SHA256_BIN="$(command -v sha256sum 2>/dev/null || echo "shasum -a 256")"

# We need EITHER openssl (>= 3.0 with ed25519 rawin support) OR node for ed25519 verify.
HAVE_OPENSSL_ED25519=0
if command -v openssl >/dev/null 2>&1; then
  OSSL_VER="$(openssl version 2>/dev/null | awk '{print $2}' | head -c 1)"
  if [ "${OSSL_VER:-0}" -ge 3 ] 2>/dev/null; then HAVE_OPENSSL_ED25519=1; fi
fi
HAVE_NODE=0
if command -v node >/dev/null 2>&1; then HAVE_NODE=1; fi
if [ $HAVE_OPENSSL_ED25519 -eq 0 ] && [ $HAVE_NODE -eq 0 ]; then
  echo "✗ need either openssl >= 3.0 or node to verify the Ed25519 signature" >&2
  exit 1
fi

# ─── fetch ──────────────────────────────────────────────────────────────
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT

echo "→ fetching installer + verification material from $BASE"
curl -fsSL "$BASE/install.sh"        -o "$TMP/install.sh"
curl -fsSL "$BASE/install.sh.sig"    -o "$TMP/install.sh.sig"
curl -fsSL "$BASE/install.sh.sha256" -o "$TMP/install.sh.sha256"
curl -fsSL "$BASE/pubkey.pem"        -o "$TMP/pubkey.pem"

# ─── verify pubkey fingerprint matches the value pinned in this script ──
SERVED_FPR="$(openssl pkey -in "$TMP/pubkey.pem" -pubin -outform DER 2>/dev/null | $SHA256_BIN | awk '{print $1}')"
if [ "$SERVED_FPR" != "$PINNED_PUBKEY_FPR" ]; then
  echo "✗ pubkey fingerprint mismatch — refusing to proceed"
  echo "  served:  $SERVED_FPR"
  echo "  pinned:  $PINNED_PUBKEY_FPR"
  echo ""
  echo "  If you believe this is a legitimate key rotation, the new pubkey"
  echo "  should be published under a signature from the prior key. Details"
  echo "  at https://zentient.studio/pto/security.txt. Do not proceed until"
  echo "  the rotation is verified."
  exit 1
fi

# ─── verify SHA-256 ─────────────────────────────────────────────────────
( cd "$TMP" && $SHA256_BIN -c install.sh.sha256 ) || {
  echo "✗ SHA-256 check failed — refusing to execute"
  exit 1
}

# ─── verify Ed25519 signature ───────────────────────────────────────────
verify_openssl() {
  openssl pkeyutl -verify \
    -pubin -inkey "$TMP/pubkey.pem" \
    -rawin -in "$TMP/install.sh" \
    -sigfile "$TMP/install.sh.sig" \
    > /dev/null 2>&1
}
verify_node() {
  node - "$TMP/install.sh" "$TMP/install.sh.sig" "$TMP/pubkey.pem" <<'JS'
  const crypto = require('crypto');
  const fs = require('fs');
  const [,, data, sig, pub] = process.argv;
  const ok = crypto.verify(
    null,
    fs.readFileSync(data),
    crypto.createPublicKey(fs.readFileSync(pub, 'utf8')),
    fs.readFileSync(sig)
  );
  process.exit(ok ? 0 : 1);
JS
}

VERIFIED=0
if [ $HAVE_OPENSSL_ED25519 -eq 1 ] && verify_openssl; then VERIFIED=1; fi
if [ $VERIFIED -eq 0 ] && [ $HAVE_NODE -eq 1 ] && verify_node; then VERIFIED=1; fi

if [ $VERIFIED -eq 0 ]; then
  echo "✗ Ed25519 signature verification failed — refusing to execute"
  echo ""
  echo "  Someone may have tampered with install.sh between our origin"
  echo "  and your machine. Please report to https://zentient.studio/pto/security.txt"
  exit 1
fi

echo "✓ pubkey fingerprint matches pinned value"
echo "✓ SHA-256 verified"
echo "✓ Ed25519 signature verified"
echo ""
echo "→ executing verified install.sh"
echo ""

# ─── execute ────────────────────────────────────────────────────────────
# Pass through any args we received (e.g. --dry-run, --uninstall)
bash "$TMP/install.sh" "$@"
