#!/bin/bash
set -euo pipefail

# Database Gateway runtime setup:
#   1. wait for the Cloudron postgresql addon (storage for profiles/bookmarks/
#      query results)
#   2. seed /app/data/config.json + /app/data/opa/ on first run
#   3. apply the embedded schema migrations (migrate-up)
#   4. exec the gateway (web UI + LRPC API on 0.0.0.0:8080)

CONFIG_PATH="/app/data/config.json"
OPA_DIR="/app/data/opa"
COOKIE_SECRET_PATH="/app/data/.cookie_secret"

# --- 1. wait for PostgreSQL -------------------------------------------------
DB_HOST=${CLOUDRON_POSTGRESQL_HOST:-127.0.0.1}
DB_PORT=${CLOUDRON_POSTGRESQL_PORT:-5432}
DB_NAME=${CLOUDRON_POSTGRESQL_DATABASE:-dbgw}
DB_USER=${CLOUDRON_POSTGRESQL_USERNAME:-dbgw}
DB_PASSWORD=${CLOUDRON_POSTGRESQL_PASSWORD}

echo "Waiting for PostgreSQL at ${DB_HOST}:${DB_PORT} ..."
until PGPASSWORD="${DB_PASSWORD}" psql -h "${DB_HOST}" -p "${DB_PORT}" -U "${DB_USER}" -d "${DB_NAME}" -c '\q' >/dev/null 2>&1; do
  echo "PostgreSQL is unavailable - sleeping"
  sleep 2
done
echo "PostgreSQL is up"

# --- 2. seed persistent configuration ---------------------------------------
# Persistent cookie secret (rotating it would invalidate live sessions).
if [[ ! -f "${COOKIE_SECRET_PATH}" ]]; then
  umask 077
  openssl rand -hex 32 > "${COOKIE_SECRET_PATH}"
  echo "Generated new cookie secret"
fi
COOKIE_SECRET=$(cat "${COOKIE_SECRET_PATH}")

# Default OPA policy: Cloudron "admins" see every target and may run any op;
# everyone else is denied until an operator extends the policy. Edit with the
# Cloudron file manager; changes apply on restart.
mkdir -p "${OPA_DIR}"
if [[ ! -f "${OPA_DIR}/simple.rego" ]]; then
  cat > "${OPA_DIR}/simple.rego" <<'EOF'
package gateway

# Default Cloudron policy: the admins group is unrestricted; everyone else
# is denied until an operator edits this file (input.subjects contains
# user:<email> and role:<role> principals).
default allow_target := false
default allow_query := false

allow_target if {
    "role:admin" in input.subjects
}

allow_query if {
    "role:admin" in input.subjects
}
EOF
  echo "Seeded default OPA policy at ${OPA_DIR}/simple.rego"
fi

# Seed the app config once (jq handles escaping of secrets into JSON). OIDC
# comes from the Cloudron platform identity provider; targets (the databases
# this gateway may reach) are added by the operator by editing
# ${CONFIG_PATH} with the Cloudron file manager.
if [[ ! -f "${CONFIG_PATH}" ]]; then
  jq -n \
    --arg db_host "${DB_HOST}" \
    --arg db_name "${DB_NAME}" \
    --arg db_user "${DB_USER}" \
    --arg db_password "${DB_PASSWORD}" \
    --argjson db_port "${DB_PORT}" \
    --arg issuer "${CLOUDRON_OIDC_ISSUER}" \
    --arg client_id "${CLOUDRON_OIDC_CLIENT_ID}" \
    --arg client_secret "${CLOUDRON_OIDC_CLIENT_SECRET}" \
    --arg origin "${CLOUDRON_APP_ORIGIN}" \
    --arg cookie_secret "${COOKIE_SECRET}" \
    --arg opa_dir "${OPA_DIR}" \
    '{
      targets: [],
      users: {
        client_id: $client_id,
        client_secret: $client_secret,
        issuer_url: $issuer,
        redirect_url: ($origin + "/auth/callback"),
        scopes: ["openid", "profile", "email", "groups"],
        role_claim: "groups",
        role_mapping: {
          admins: "admin",
          users: "user"
        }
      },
      policy: { path: $opa_dir },
      facade: {
        port: 8080,
        cookie_secret: $cookie_secret,
        unsafe_cors_allow_all: false
      },
      storage: {
        host: $db_host,
        port: $db_port,
        database: $db_name,
        username: $db_user,
        password: $db_password,
        use_ssl: false,
        max_pool_size: 16
      }
    }' > "${CONFIG_PATH}"
  chmod 600 "${CONFIG_PATH}"
  echo "Seeded config at ${CONFIG_PATH}"
fi

# --- 3. migrations -----------------------------------------------------------
echo "Applying database migrations ..."
/usr/local/bin/database-gateway -c "${CONFIG_PATH}" migrate-up

# --- 4. run --------------------------------------------------------------------
echo "Starting Database Gateway on :8080 ..."
exec /usr/local/bin/database-gateway -c "${CONFIG_PATH}" run
