#!/bin/bash
# assign-port.sh
# Automatically assigns next available port to a CLI site
#
# Usage: ./assign-port.sh <site-name> [environment]
#
# Environment: production (default) or development
# Port ranges:
#   - Production: 9200-9299
#   - Development: 3200-3299

set -e

SITE_NAME=$1
ENV=${2:-"production"}

if [ -z "$SITE_NAME" ]; then
  echo "Usage: $0 <site-name> [environment]"
  echo ""
  echo "Examples:"
  echo "  $0 my-site production    # Assigns port 9200-9299"
  echo "  $0 my-site development   # Assigns port 3200-3299"
  exit 1
fi

if [ "$ENV" != "production" ] && [ "$ENV" != "development" ]; then
  echo "❌ Invalid environment: $ENV"
  echo "   Must be 'production' or 'development'"
  exit 1
fi

# Get script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PORTS_FILE="$SCRIPT_DIR/../ports.json"

if [ ! -f "$PORTS_FILE" ]; then
  echo "❌ ports.json not found at: $PORTS_FILE"
  exit 1
fi

echo "🔍 Port assignment for: $SITE_NAME ($ENV)"
echo ""

# Check if already assigned
EXISTING_PORT=$(jq -r ".\"$SITE_NAME\" // empty" "$PORTS_FILE")

if [ -n "$EXISTING_PORT" ] && [ "$EXISTING_PORT" != "null" ]; then
  echo "⚠️  Port already assigned: $EXISTING_PORT"
  echo ""
  read -p "Reassign to new port? (y/n): " -n 1 -r
  echo ""

  if [[ ! $REPLY =~ ^[Yy]$ ]]; then
    echo "❌ Cancelled. Keeping existing port: $EXISTING_PORT"
    exit 0
  fi
fi

# Get next available port from metadata
NEXT_PORT=$(jq -r "._meta.next_available.$ENV" "$PORTS_FILE")

if [ -z "$NEXT_PORT" ] || [ "$NEXT_PORT" = "null" ]; then
  echo "❌ No next_available port found in metadata for $ENV"
  exit 1
fi

# Check if port is already in use (by another site in registry)
CONFLICT=$(jq -r "to_entries | .[] | select(.key != \"_meta\" and .value == $NEXT_PORT) | .key" "$PORTS_FILE")

if [ -n "$CONFLICT" ]; then
  echo "❌ Port $NEXT_PORT is already assigned to: $CONFLICT"
  echo ""
  echo "Updating next_available to skip conflict..."

  # Increment until we find an available port
  if [ "$ENV" = "production" ]; then
    MAX_PORT=9299
  else
    MAX_PORT=3299
  fi

  while [ $NEXT_PORT -le $MAX_PORT ]; do
    NEXT_PORT=$((NEXT_PORT + 1))
    CONFLICT=$(jq -r "to_entries | .[] | select(.key != \"_meta\" and .value == $NEXT_PORT) | .key" "$PORTS_FILE")

    if [ -z "$CONFLICT" ]; then
      echo "✅ Found available port: $NEXT_PORT"
      break
    fi
  done

  if [ $NEXT_PORT -gt $MAX_PORT ]; then
    echo "❌ No available ports in range!"
    exit 1
  fi
fi

# Assign port
echo "📌 Assigning port $NEXT_PORT to $SITE_NAME"

# Update ports.json
TMP_FILE=$(mktemp)

jq \
  --arg site "$SITE_NAME" \
  --argjson port "$NEXT_PORT" \
  --arg env "$ENV" \
  --arg date "$(date +%Y-%m-%d)" \
  '.[$site] = $port | ._meta.next_available[$env] = ($port + 1) | ._meta.last_updated = $date' \
  "$PORTS_FILE" > "$TMP_FILE"

mv "$TMP_FILE" "$PORTS_FILE"

echo "✅ Port assigned successfully!"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "  Site: $SITE_NAME"
echo "  Port: $NEXT_PORT"
echo "  Environment: $ENV"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""

# Show next steps
echo "Next steps:"
echo ""
echo "1. Update ecosystem.config.js:"
echo "   env: { PORT: '$NEXT_PORT' }"
echo ""
echo "2. Update nginx location block:"
echo "   location /cli/$SITE_NAME {"
echo "     proxy_pass http://127.0.0.1:$NEXT_PORT;"
echo "   }"
echo ""
echo "3. Restart services:"
echo "   pm2 restart cli-$SITE_NAME"
echo "   sudo systemctl reload nginx"
echo ""

# Check if port is available on current machine
if command -v lsof >/dev/null 2>&1; then
  if lsof -i ":$NEXT_PORT" >/dev/null 2>&1; then
    echo "⚠️  WARNING: Port $NEXT_PORT is currently in use on this machine:"
    lsof -i ":$NEXT_PORT" | head -2
    echo ""
  fi
fi

exit 0
