#!/usr/bin/env bash
# Guided STECH device onboarding — enroll, bind user, verify auth, rotate pairing secret.
# Usage:
#   SAGA_ENROLLMENT_CODE=RUNE-XXXX-XXXX-XXXX ./stech-onboard.sh
#   SAGA_DEVICE_PAIRING_SECRET=... ./stech-onboard.sh   # legacy IT only
#   ./stech-onboard.sh --factory-manifest batch.json --device-id stech-STECH-000001
set -euo pipefail

SAGA_URL="${SAGA_URL:-http://127.0.0.1:8080}"
TENANT="${TENANT:-your-tenant}"
AGENT_BIN="${STECH_AGENT_BIN:-stech-agent}"
WORKDIR="${STECH_ONBOARD_DIR:-/tmp/stech-onboard-$$}"
FACTORY_MANIFEST=""
FACTORY_DEVICE_ID=""
ADMIN_EMAIL=""
ADMIN_PASSWORD=""
SET_PIN=""
SKIP_ROTATE=0
SKIP_SERVE=0

usage() {
  echo "Usage: $0 [options]" >&2
  echo "  --saga-url URL        Saga base URL (default: $SAGA_URL)" >&2
  echo "  --tenant SLUG         Tenant slug (default: $TENANT)" >&2
  echo "  --admin-email EMAIL   Admin for bind step" >&2
  echo "  --admin-password PASS Admin password" >&2
  echo "  --factory-manifest F  Use factory-burned identity from manifest" >&2
  echo "  --device-id ID        Device id inside factory manifest" >&2
  echo "  --pin DIGITS          Set device PIN after enroll" >&2
  echo "  --skip-rotate         Do not rotate pairing secret after success" >&2
  echo "  --skip-serve          Do not start stech-agent serve" >&2
  exit 1
}

while [ $# -gt 0 ]; do
  case "$1" in
    --saga-url) SAGA_URL="$2"; shift 2 ;;
    --tenant) TENANT="$2"; shift 2 ;;
    --admin-email) ADMIN_EMAIL="$2"; shift 2 ;;
    --admin-password) ADMIN_PASSWORD="$2"; shift 2 ;;
    --factory-manifest) FACTORY_MANIFEST="$2"; shift 2 ;;
    --device-id) FACTORY_DEVICE_ID="$2"; shift 2 ;;
    --pin) SET_PIN="$2"; shift 2 ;;
    --skip-rotate) SKIP_ROTATE=1; shift ;;
    --skip-serve) SKIP_SERVE=1; shift ;;
    -h|--help) usage ;;
    *) echo "Unknown: $1" >&2; usage ;;
  esac
done

command -v "$AGENT_BIN" >/dev/null || { echo "ERROR: $AGENT_BIN not found" >&2; exit 1; }
command -v curl >/dev/null || { echo "ERROR: curl required" >&2; exit 1; }
command -v python3 >/dev/null || { echo "ERROR: python3 required" >&2; exit 1; }

mkdir -p "$WORKDIR"
export STECH_AGENT_CONFIG_DIR="$WORKDIR"

cleanup() {
  if [ "${KEEP_WORKDIR:-0}" != "1" ]; then
    rm -rf "$WORKDIR"
  fi
}
trap cleanup EXIT

step() { echo ""; echo "==> $*"; }

step "Check Saga deployment"
curl -sf "$SAGA_URL/api/v1/deployment" | python3 -c \
  "import sys,json; d=json.load(sys.stdin); assert d.get('device_trust_enabled'); print('Saga OK:', d.get('display_name', 'Saga'))"

if [ -n "$FACTORY_MANIFEST" ]; then
  [ -n "$FACTORY_DEVICE_ID" ] || { echo "ERROR: --device-id required with --factory-manifest" >&2; exit 1; }
  step "Install factory identity"
  "$AGENT_BIN" factory install --manifest "$FACTORY_MANIFEST" --device-id "$FACTORY_DEVICE_ID" \
    --saga-url "$SAGA_URL" --tenant "$TENANT"
else
  step "Initialize new device identity"
  "$AGENT_BIN" init --tenant "$TENANT" --saga-url "$SAGA_URL" --label "STECH workstation"
fi

DEVICE_ID=$("$AGENT_BIN" status | python3 -c "import sys,json; print(json.load(sys.stdin)['device_id'])")
echo "device_id=$DEVICE_ID"

step "Enroll with Saga"
if [ -n "$FACTORY_MANIFEST" ]; then
  echo "    (factory pre-register — no pairing secret if admin imported batch)"
  if [ -n "${SAGA_DEVICE_PAIRING_SECRET:-}" ]; then
    "$AGENT_BIN" enroll --pairing-secret "$SAGA_DEVICE_PAIRING_SECRET"
  else
    "$AGENT_BIN" enroll
  fi
elif [ -n "${SAGA_ENROLLMENT_CODE:-}" ]; then
  "$AGENT_BIN" enroll --enrollment-code "$SAGA_ENROLLMENT_CODE"
else
  : "${SAGA_DEVICE_PAIRING_SECRET:?Set SAGA_ENROLLMENT_CODE or SAGA_DEVICE_PAIRING_SECRET for enroll}"
  "$AGENT_BIN" enroll --pairing-secret "$SAGA_DEVICE_PAIRING_SECRET"
fi

if [ -n "$SET_PIN" ]; then
  step "Set device PIN"
  "$AGENT_BIN" pin set --pin "$SET_PIN"
fi

if [ -z "$ADMIN_EMAIL" ]; then
  read -r -p "Admin email for bind step: " ADMIN_EMAIL
fi
if [ -z "$ADMIN_PASSWORD" ]; then
  read -r -s -p "Admin password: " ADMIN_PASSWORD
  echo
fi

step "Bind device to user"
COOKIE_JAR="$WORKDIR/cookies.txt"
LOGIN_JSON=$(curl -sf -c "$COOKIE_JAR" -X POST "$SAGA_URL/api/v1/auth/login" \
  -H "Content-Type: application/json" \
  -d "{\"tenant\":\"$TENANT\",\"email\":\"$ADMIN_EMAIL\",\"password\":\"$ADMIN_PASSWORD\"}")
TOKEN=$(echo "$LOGIN_JSON" | python3 -c "import sys,json; print(json.load(sys.stdin).get('access_token',''))" 2>/dev/null || true)

read -r -p "User email to bind this device to: " BIND_EMAIL
USER_ID=$(curl -sf ${TOKEN:+-H "Authorization: Bearer $TOKEN"} ${TOKEN:+-b "$COOKIE_JAR"} \
  "$SAGA_URL/api/v1/org/users" 2>/dev/null | python3 -c \
  "import sys,json; email=sys.argv[1].lower(); users=json.load(sys.stdin); \
m=[u['id'] for u in users if u.get('email','').lower()==email and u.get('active')]; \
print(m[0] if m else '')" "$BIND_EMAIL" 2>/dev/null || true)

if [ -z "$USER_ID" ] && [ -n "${DATABASE_URL:-}" ] && command -v psql >/dev/null; then
  USER_ID=$(psql "$DATABASE_URL" -tAc \
    "SELECT u.id FROM users u JOIN tenants t ON t.id=u.tenant_id \
     WHERE t.slug='$TENANT' AND lower(u.email)=lower('$BIND_EMAIL') AND u.active LIMIT 1")
fi
[ -n "$USER_ID" ] || { echo "ERROR: user not found: $BIND_EMAIL" >&2; exit 1; }

AUTH_ARGS=()
if [ -n "$TOKEN" ]; then AUTH_ARGS=(-H "Authorization: Bearer $TOKEN"); else AUTH_ARGS=(-b "$COOKIE_JAR"); fi
curl -sf -X PUT "${AUTH_ARGS[@]}" -H "Content-Type: application/json" \
  -d "{\"user_id\":\"$USER_ID\"}" \
  "$SAGA_URL/api/v1/ops/devices/$DEVICE_ID/bind" >/dev/null
echo "bound to $BIND_EMAIL"

step "Verify device auth"
if [ -n "$SET_PIN" ]; then
  STECH_AGENT_CONFIG_DIR="$WORKDIR" "$AGENT_BIN" auth 2>/dev/null && \
    echo "WARN: auth without PIN succeeded (PIN may not apply to CLI auth)" || true
fi
AUTH_OUT=$("$AGENT_BIN" auth)
echo "$AUTH_OUT" | python3 -c \
  "import sys,json; d=json.load(sys.stdin); assert d['ok'] and d['access_token']; print('auth ok:', d['email'])"

if [ "$SKIP_ROTATE" = "0" ] && [ -z "$FACTORY_MANIFEST" ]; then
  step "Rotate pairing secret (one-time enroll token)"
  ROTATE=$(curl -sf -X POST "${AUTH_ARGS[@]}" -H "Content-Type: application/json" \
    -d '{}' "$SAGA_URL/api/v1/ops/devices/rotate-pairing-secret")
  NEW_SECRET=$(echo "$ROTATE" | python3 -c "import sys,json; print(json.load(sys.stdin)['pairing_secret'])")
  echo "New pairing secret (update /etc/saga/saga.env):"
  echo "$NEW_SECRET"
fi

if [ "$SKIP_SERVE" = "0" ]; then
  step "Start STECH Login Agent (background)"
  if systemctl is-enabled stech-agent.service >/dev/null 2>&1; then
    sudo systemctl restart stech-agent.service
    echo "stech-agent.service restarted"
  else
    echo "Run: stech-agent serve"
    echo "Or install systemd unit from docs/IDENTITY_3.0_LOCAL.md"
  fi
fi

step "Onboarding complete"
echo "Device $DEVICE_ID is ready for browser sign-in."
echo "Config stored in: $WORKDIR (set KEEP_WORKDIR=1 to preserve)"