#!/usr/bin/env bash
# ============================================================================
# dev-up.sh — bring up the DEV Synapse for RFC-001 P1 (presence)
# ============================================================================
#
#   *** DEV-ONLY. LOCAL SANDBOX. This script must never be pointed at live
#       infra. It writes only into infra/matrix/.data (gitignored) and drives
#       a dedicated compose project (matrix-p1-dev). ***
#
# It renders the Synapse config + appservice registration from the committed
# templates (envsubst), generates a DEV signing key + self-signed TLS cert,
# and starts Synapse. All topology facts come from the environment with dev
# defaults (RFC-002 G2: nothing hardcoded).
# ----------------------------------------------------------------------------
set -euo pipefail

HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DATA="${HERE}/.data"
COMPOSE=(docker compose -f "${HERE}/docker-compose.dev.yml")

# ---- Topology inputs (dev defaults; override via env) ----------------------
export MATRIX_SERVER_NAME="${MATRIX_SERVER_NAME:-matrix.localhost}"
export MOSAIC_AS_ID="${MOSAIC_AS_ID:-mosaic-as}"
export MATRIX_HTTP_PORT="${MATRIX_HTTP_PORT:-18008}"
export MATRIX_TLS_PORT="${MATRIX_TLS_PORT:-18448}"

# ---- DEV secrets (throwaway; regenerated if absent) ------------------------
SECRETS_ENV="${DATA}/dev-secrets.env"
mkdir -p "${DATA}"
if [[ ! -f "${SECRETS_ENV}" ]]; then
  {
    echo "MOSAIC_AS_TOKEN=devas_$(openssl rand -hex 16)"
    echo "MOSAIC_HS_TOKEN=devhs_$(openssl rand -hex 16)"
    echo "SYNAPSE_REG_SHARED_SECRET=devreg_$(openssl rand -hex 16)"
    echo "SYNAPSE_MACAROON_SECRET=devmac_$(openssl rand -hex 16)"
    echo "SYNAPSE_FORM_SECRET=devform_$(openssl rand -hex 16)"
  } > "${SECRETS_ENV}"
  echo "[dev-up] generated throwaway DEV secrets -> ${SECRETS_ENV}"
fi
# shellcheck disable=SC1090
set -a; source "${SECRETS_ENV}"; set +a

# DEV: let the synapse container user (uid 991) write the sqlite db / media.
chmod 0777 "${DATA}" || true

# ---- Render config from templates ------------------------------------------
envsubst < "${HERE}/synapse/homeserver.dev.yaml.tpl" > "${DATA}/homeserver.yaml"
envsubst < "${HERE}/appservice/mosaic-as.dev.yaml.tpl" > "${DATA}/${MOSAIC_AS_ID}.yaml"
cp "${HERE}/synapse/log.config" "${DATA}/log.config"
echo "[dev-up] rendered homeserver.yaml + ${MOSAIC_AS_ID}.yaml (server_name=${MATRIX_SERVER_NAME})"

# ---- DEV signing key -------------------------------------------------------
# Generate as the synapse container user (uid 991) so the running container
# can read it; owned-by-991 mode-600 is fine (the container IS 991).
SIGNING_KEY="${DATA}/${MATRIX_SERVER_NAME}.signing.key"
if [[ ! -f "${SIGNING_KEY}" ]]; then
  docker run --rm --user 991:991 -v "${DATA}:/data" --entrypoint generate_signing_key \
    matrixdotorg/synapse:latest -o "/data/${MATRIX_SERVER_NAME}.signing.key"
  echo "[dev-up] generated DEV signing key"
fi

# ---- DEV self-signed TLS cert (A1) -----------------------------------------
if [[ ! -f "${DATA}/dev-cert.pem" ]]; then
  openssl req -x509 -newkey rsa:2048 -nodes \
    -keyout "${DATA}/dev-key.pem" -out "${DATA}/dev-cert.pem" \
    -days 90 -subj "/CN=${MATRIX_SERVER_NAME}" \
    -addext "subjectAltName=DNS:${MATRIX_SERVER_NAME},DNS:localhost,IP:127.0.0.1" >/dev/null 2>&1
  echo "[dev-up] generated DEV self-signed TLS cert for ${MATRIX_SERVER_NAME}"
fi
# Files hermes owns must be world-readable so the synapse (uid 991) container
# can read them (DEV-only; the signing key stays owned by 991 from above).
chmod 0644 "${DATA}/dev-cert.pem" "${DATA}/dev-key.pem" \
  "${DATA}/homeserver.yaml" "${DATA}/${MOSAIC_AS_ID}.yaml" "${DATA}/log.config" || true

# ---- Element config (optional human view, A4) ------------------------------
cat > "${DATA}/element-config.json" <<JSON
{
  "default_server_config": {
    "m.homeserver": {
      "base_url": "https://localhost:${MATRIX_TLS_PORT}",
      "server_name": "${MATRIX_SERVER_NAME}"
    }
  },
  "disable_guests": true,
  "brand": "Mosaic P1 (DEV)"
}
JSON

# ---- Boot ------------------------------------------------------------------
"${COMPOSE[@]}" up -d synapse

echo -n "[dev-up] waiting for Synapse health"
for _ in $(seq 1 60); do
  status="$("${COMPOSE[@]}" ps --format '{{.Health}}' synapse 2>/dev/null || true)"
  if [[ "${status}" == "healthy" ]]; then echo " ... healthy"; break; fi
  echo -n "."; sleep 2
done

if ! curl -fsS "http://127.0.0.1:${MATRIX_HTTP_PORT}/health" >/dev/null 2>&1; then
  echo "[dev-up] ERROR: Synapse did not become healthy" >&2
  "${COMPOSE[@]}" logs --tail 60 synapse >&2 || true
  exit 1
fi

echo "[dev-up] Synapse UP:"
echo "         plain HTTP : http://127.0.0.1:${MATRIX_HTTP_PORT}"
echo "         TLS        : https://127.0.0.1:${MATRIX_TLS_PORT} (self-signed, DEV)"
echo "         server_name: ${MATRIX_SERVER_NAME}   registration: OFF"
