#!/usr/bin/env bash
# ==============================================
# Matrix Bot Account Setup Script
# ==============================================
#
# Creates the Mosaic bot user on the local Synapse instance and retrieves
# an access token. Idempotent — safe to run multiple times.
#
# Usage:
#   docker/matrix/scripts/setup-bot.sh
#   docker/matrix/scripts/setup-bot.sh --username custom-bot --password custom-pass
#
# Prerequisites:
#   - Synapse must be running (docker compose -f ... up synapse)
#   - Synapse must be healthy (check with: curl http://localhost:8008/health)
#
# Output:
#   Prints the environment variables needed for MatrixService configuration.
#
# ==============================================

set -euo pipefail

# Defaults
SYNAPSE_URL="${SYNAPSE_URL:-http://localhost:8008}"
BOT_USERNAME="${BOT_USERNAME:-mosaic-bot}"
BOT_PASSWORD="${BOT_PASSWORD:-mosaic-bot-dev-password}"
BOT_DISPLAY_NAME="${BOT_DISPLAY_NAME:-Mosaic Bot}"
ADMIN_USERNAME="${ADMIN_USERNAME:-admin}"
ADMIN_PASSWORD="${ADMIN_PASSWORD:-admin-dev-password}"

# Parse arguments
while [[ $# -gt 0 ]]; do
  case $1 in
    --username) BOT_USERNAME="$2"; shift 2 ;;
    --password) BOT_PASSWORD="$2"; shift 2 ;;
    --synapse-url) SYNAPSE_URL="$2"; shift 2 ;;
    --admin-username) ADMIN_USERNAME="$2"; shift 2 ;;
    --admin-password) ADMIN_PASSWORD="$2"; shift 2 ;;
    --help|-h)
      echo "Usage: $0 [OPTIONS]"
      echo ""
      echo "Options:"
      echo "  --username NAME        Bot username (default: mosaic-bot)"
      echo "  --password PASS        Bot password (default: mosaic-bot-dev-password)"
      echo "  --synapse-url URL      Synapse URL (default: http://localhost:8008)"
      echo "  --admin-username NAME  Admin username (default: admin)"
      echo "  --admin-password PASS  Admin password (default: admin-dev-password)"
      echo "  --help, -h             Show this help"
      exit 0
      ;;
    *) echo "Unknown option: $1"; exit 1 ;;
  esac
done

echo "=== Mosaic Stack — Matrix Bot Setup ==="
echo ""
echo "Synapse URL: ${SYNAPSE_URL}"
echo "Bot username: ${BOT_USERNAME}"
echo ""

# Wait for Synapse to be ready
echo "Checking Synapse health..."
for i in $(seq 1 30); do
  if curl -fsSo /dev/null "${SYNAPSE_URL}/health" 2>/dev/null; then
    echo "Synapse is healthy."
    break
  fi
  if [ "$i" -eq 30 ]; then
    echo "ERROR: Synapse is not responding at ${SYNAPSE_URL}/health after 30 attempts."
    echo "Make sure Synapse is running:"
    echo "  docker compose -f docker/docker-compose.yml -f docker/docker-compose.matrix.yml up -d"
    exit 1
  fi
  echo "  Waiting for Synapse... (attempt ${i}/30)"
  sleep 2
done

echo ""

# Step 1: Register admin account (if not exists)
echo "Step 1: Registering admin account '${ADMIN_USERNAME}'..."
ADMIN_REGISTER_RESPONSE=$(curl -sS -X POST "${SYNAPSE_URL}/_synapse/admin/v1/register" \
  -H "Content-Type: application/json" \
  -d "{}" 2>/dev/null || true)

NONCE=$(echo "${ADMIN_REGISTER_RESPONSE}" | python3 -c "import sys,json; print(json.load(sys.stdin).get('nonce',''))" 2>/dev/null || true)

if [ -n "${NONCE}" ]; then
  # Generate HMAC for admin registration using the nonce
  # For dev, we use register_new_matrix_user via docker exec instead
  echo "  Using docker exec to register admin via Synapse CLI..."
  docker exec mosaic-synapse register_new_matrix_user \
    -u "${ADMIN_USERNAME}" \
    -p "${ADMIN_PASSWORD}" \
    -a \
    -c /data/homeserver.yaml \
    http://localhost:8008 2>/dev/null && echo "  Admin account created." || echo "  Admin account already exists (or registration failed — continuing)."
else
  echo "  Attempting registration via docker exec..."
  docker exec mosaic-synapse register_new_matrix_user \
    -u "${ADMIN_USERNAME}" \
    -p "${ADMIN_PASSWORD}" \
    -a \
    -c /data/homeserver.yaml \
    http://localhost:8008 2>/dev/null && echo "  Admin account created." || echo "  Admin account already exists (or registration failed — continuing)."
fi

echo ""

# Step 2: Get admin access token
echo "Step 2: Obtaining admin access token..."
ADMIN_LOGIN_RESPONSE=$(curl -sS -X POST "${SYNAPSE_URL}/_matrix/client/v3/login" \
  -H "Content-Type: application/json" \
  -d "$(jq -n \
    --arg user "$ADMIN_USERNAME" \
    --arg pw "$ADMIN_PASSWORD" \
    '{type: "m.login.password", identifier: {type: "m.id.user", user: $user}, password: $pw}')" \
  2>/dev/null)

ADMIN_TOKEN=$(echo "${ADMIN_LOGIN_RESPONSE}" | python3 -c "import sys,json; print(json.load(sys.stdin).get('access_token',''))" 2>/dev/null || true)

if [ -z "${ADMIN_TOKEN}" ]; then
  echo "ERROR: Could not obtain admin access token."
  echo "Response: ${ADMIN_LOGIN_RESPONSE}"
  echo ""
  echo "Try registering the admin account manually:"
  echo "  docker exec -it mosaic-synapse register_new_matrix_user -u ${ADMIN_USERNAME} -p ${ADMIN_PASSWORD} -a -c /data/homeserver.yaml http://localhost:8008"
  exit 1
fi
echo "  Admin token obtained."

echo ""

# Step 3: Register bot account via admin API (idempotent)
echo "Step 3: Registering bot account '${BOT_USERNAME}'..."
BOT_REGISTER_RESPONSE=$(curl -sS -X PUT "${SYNAPSE_URL}/_synapse/admin/v2/users/@${BOT_USERNAME}:localhost" \
  -H "Authorization: Bearer ${ADMIN_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "$(jq -n \
    --arg pw "$BOT_PASSWORD" \
    --arg dn "$BOT_DISPLAY_NAME" \
    '{password: $pw, displayname: $dn, admin: false, deactivated: false}')" \
  2>/dev/null)

BOT_EXISTS=$(echo "${BOT_REGISTER_RESPONSE}" | python3 -c "import sys,json; d=json.load(sys.stdin); print('yes' if d.get('name') else 'no')" 2>/dev/null || echo "no")

if [ "${BOT_EXISTS}" = "yes" ]; then
  echo "  Bot account '@${BOT_USERNAME}:localhost' is ready."
else
  echo "  WARNING: Bot registration response unexpected: ${BOT_REGISTER_RESPONSE}"
  echo "  Continuing anyway — bot may already exist."
fi

echo ""

# Step 4: Get bot access token
echo "Step 4: Obtaining bot access token..."
BOT_LOGIN_RESPONSE=$(curl -sS -X POST "${SYNAPSE_URL}/_matrix/client/v3/login" \
  -H "Content-Type: application/json" \
  -d "$(jq -n \
    --arg user "$BOT_USERNAME" \
    --arg pw "$BOT_PASSWORD" \
    '{type: "m.login.password", identifier: {type: "m.id.user", user: $user}, password: $pw}')" \
  2>/dev/null)

BOT_TOKEN=$(echo "${BOT_LOGIN_RESPONSE}" | python3 -c "import sys,json; print(json.load(sys.stdin).get('access_token',''))" 2>/dev/null || true)

if [ -z "${BOT_TOKEN}" ]; then
  echo "ERROR: Could not obtain bot access token."
  echo "Response: ${BOT_LOGIN_RESPONSE}"
  exit 1
fi

echo "  Bot token obtained."
echo ""

# Step 5: Output configuration
echo "============================================"
echo "  Matrix Bot Setup Complete"
echo "============================================"
echo ""
echo "Add the following to your .env file:"
echo ""
echo "  # Matrix Bridge Configuration"
echo "  MATRIX_HOMESERVER_URL=http://localhost:8008"
echo "  MATRIX_ACCESS_TOKEN=${BOT_TOKEN}"
echo "  MATRIX_BOT_USER_ID=@${BOT_USERNAME}:localhost"
echo "  MATRIX_SERVER_NAME=localhost"
echo ""
echo "Or, if running the API inside Docker (same compose network):"
echo ""
echo "  MATRIX_HOMESERVER_URL=http://synapse:8008"
echo "  MATRIX_ACCESS_TOKEN=${BOT_TOKEN}"
echo "  MATRIX_BOT_USER_ID=@${BOT_USERNAME}:localhost"
echo "  MATRIX_SERVER_NAME=localhost"
echo ""
echo "Element Web is available at: http://localhost:8501"
echo "  Login with any registered user to test messaging."
echo ""
echo "Admin account: ${ADMIN_USERNAME} / ${ADMIN_PASSWORD}"
echo "Bot account:   ${BOT_USERNAME} / ${BOT_PASSWORD}"
echo "============================================"
