#!/bin/bash
# Manages Neon database branches for this app
# Usage:
#   ./scripts/neon-setup          # Create branch, write .env
#   ./scripts/neon-setup cleanup  # Delete branch, remove .env
#
# Requires: NEON_API_KEY, NEON_PROJECT_ID env vars
# Optional: APP_NAME (defaults to the name recorded in .env by a prior setup, then the app directory name)
#           NEON_ROLE_NAME (defaults to neondb_owner)
#           NEON_COMPUTE_SIZE (defaults to 0.25-1 CU)
#           NEON_BRANCH_TTL (branch expiration, e.g., "2h", "1d", "7d")
#
# Dependencies: neonctl (npm i -g neonctl), jq

set -e

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
APP_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
# Prefer explicit APP_NAME, then the name a prior setup recorded in .env, then the directory name
if [ -z "${APP_NAME:-}" ] && [ -f "$APP_DIR/.env" ]; then
    APP_NAME="$(sed -n 's/^# APP_NAME=//p' "$APP_DIR/.env")"
fi
APP_NAME="${APP_NAME:-$(basename "$APP_DIR")}"
COMMAND="${1:-setup}"

: "${NEON_API_KEY:?NEON_API_KEY required}"
: "${NEON_PROJECT_ID:?NEON_PROJECT_ID required}"
NEON_ROLE_NAME="${NEON_ROLE_NAME:-neondb_owner}"
NEON_COMPUTE_SIZE="${NEON_COMPUTE_SIZE:-0.25-1}"
NEON_BRANCH_TTL="${NEON_BRANCH_TTL:-}"  # e.g., "2h", "1d", "7d" - empty means no expiration
DEV_BRANCH="${APP_NAME}-dev"

# Convert TTL like "2h", "1d" to ISO date string for --expires-at
ttl_to_date() {
    local ttl="$1"
    local value="${ttl%[hdwm]}"
    local unit="${ttl: -1}"
    local seconds=0

    case "$unit" in
        h) seconds=$((value * 3600)) ;;
        d) seconds=$((value * 86400)) ;;
        w) seconds=$((value * 604800)) ;;
        m) seconds=$((value * 2592000)) ;;
        *) echo "Invalid TTL unit: $unit (use h/d/w/m)" >&2; return 1 ;;
    esac

    if [[ "$OSTYPE" == "darwin"* ]]; then
        date -u -v+${seconds}S '+%Y-%m-%dT%H:%M:%SZ'
    else
        date -u -d "+${seconds} seconds" '+%Y-%m-%dT%H:%M:%SZ'
    fi
}

get_prod_branch() {
    if [ -n "${NEON_PROD_BRANCH:-}" ]; then
        echo "$NEON_PROD_BRANCH"
        return
    fi

    local branches
    branches=$(neonctl branches list --project-id "$NEON_PROJECT_ID" --output json 2>/dev/null)

    for name in main master production prod; do
        if echo "$branches" | jq -e ".[] | select(.name == \"$name\")" > /dev/null 2>&1; then
            echo "$name"
            return
        fi
    done

    local primary
    primary=$(echo "$branches" | jq -r '.[] | select(.primary == true) | .name' 2>/dev/null)
    if [ -n "$primary" ]; then
        echo "$primary"
        return
    fi

    echo "$branches" | jq -r '.[0].name'
}

branch_exists() {
    neonctl branches list --project-id "$NEON_PROJECT_ID" --output json 2>/dev/null \
        | jq -e ".[] | select(.name == \"$1\")" > /dev/null 2>&1
}

cleanup() {
    echo "Deleting branch: $DEV_BRANCH"
    if branch_exists "$DEV_BRANCH"; then
        neonctl branches delete "$DEV_BRANCH" --project-id "$NEON_PROJECT_ID"
        echo "Branch deleted: $DEV_BRANCH"
    else
        echo "Branch does not exist: $DEV_BRANCH"
    fi

    if [ -f "$APP_DIR/.env" ]; then
        rm "$APP_DIR/.env"
        echo "Removed: .env"
    fi
}

setup() {
    local prod_branch
    prod_branch=$(get_prod_branch)
    echo "App: $APP_NAME"
    echo "Branch: $DEV_BRANCH"
    echo ""

    if branch_exists "$DEV_BRANCH"; then
        echo "Branch already exists"
    else
        echo "Creating branch from $prod_branch..."
        local expires_flag=""
        if [ -n "$NEON_BRANCH_TTL" ]; then
            local expires_at
            expires_at=$(ttl_to_date "$NEON_BRANCH_TTL")
            expires_flag="--expires-at $expires_at"
            echo "Branch will expire at: $expires_at ($NEON_BRANCH_TTL from now)"
        fi
        neonctl branches create --project-id "$NEON_PROJECT_ID" --name "$DEV_BRANCH" --parent "$prod_branch" --cu "$NEON_COMPUTE_SIZE" $expires_flag
    fi

    DEV_URI=$(neonctl connection-string --project-id "$NEON_PROJECT_ID" --branch "$DEV_BRANCH" --role-name "$NEON_ROLE_NAME")

    {
        echo "# APP_NAME=$APP_NAME"
        echo "export DATABASE_URL='$DEV_URI'"
    } > "$APP_DIR/.env"
    echo ""
    echo "Written to .env:"
    cat "$APP_DIR/.env"

    # run migrations if migrations directory exists
    if [ -d "$APP_DIR/migrations" ] && [ -n "$(ls -A "$APP_DIR/migrations" 2>/dev/null)" ]; then
        echo ""
        if command -v sqlx &> /dev/null; then
            echo "Running migrations..."
            (cd "$APP_DIR" && source .env && sqlx migrate run)
            echo "Migrations complete"
        else
            echo "WARN: sqlx-cli not installed, skipping migrations"
            echo "Install: cargo install sqlx-cli --features postgres,native-tls"
            echo "Then run: source .env && sqlx migrate run"
        fi
    fi
}

case "$COMMAND" in
    cleanup)
        cleanup
        ;;
    *)
        setup
        ;;
esac
