#!/bin/bash

# Project Launch Script
# Automates setup and concurrent execution of backend and frontend servers.

set -e

# Default configuration
BACKEND_PORT=${BACKEND_PORT:-8000}
FRONTEND_PORT=${FRONTEND_PORT:-5173}
SKIP_INSTALL=false

# Help message
show_help() {
    echo "Usage: ./run.sh [options]"
    echo ""
    echo "Options:"
    echo "  --help            Show this help message"
    echo "  --skip-install    Skip dependency checks and installation"
    echo ""
    echo "Environment Variables:"
    echo "  BACKEND_PORT      Port for the backend server (default: 8000)"
    echo "  FRONTEND_PORT     Port for the frontend server (default: 5173)"
}

# Parse arguments
while [[ "$#" -gt 0 ]]; do
    case $1 in
        --help) show_help; exit 0 ;;
        --skip-install) SKIP_INSTALL=true ;;
        *) echo "Unknown parameter passed: $1"; show_help; exit 1 ;;
    esac
    shift
done

echo "Starting Project Launch Script..."

# Environment validation
validate_env() {
    echo "Validating environment..."
    
    if ! command -v python3 &> /dev/null; then
        echo "Error: python3 is not installed."
        exit 1
    fi

    if ! python3 -c 'import sys; exit(0) if sys.version_info >= (3, 9) else exit(1)'; then
        PYTHON_VERSION=$(python3 -c 'import sys; print(".".join(map(str, sys.version_info[:2])))')
        echo "Error: python3 version 3.9 or higher is required. Found $PYTHON_VERSION"
        exit 1
    fi

    if ! command -v npm &> /dev/null; then
        echo "Error: npm is not installed."
        exit 1
    fi
    
    PYTHON_VERSION=$(python3 -c 'import sys; print(".".join(map(str, sys.version_info[:2])))')
    echo "Environment validation passed (Python $PYTHON_VERSION, npm $(npm -v))"
}

validate_env

# Database connectivity preflight
check_database() {
    # Keep resolution order aligned with backend/src/core/database.py defaults.
    local DB_URL="${DATABASE_URL:-${POSTGRES_URL:-postgresql+psycopg2://postgres:postgres@localhost:5432/ss_tools}}"

    # SQLite does not require external service.
    if [[ "$DB_URL" == sqlite* ]]; then
        echo "Database preflight: sqlite detected, skipping PostgreSQL connectivity check."
        return
    fi

    local DB_HOST DB_PORT
    read -r DB_HOST DB_PORT < <(
        python3 - "$DB_URL" <<'PY'
import sys
from urllib.parse import urlparse

url = sys.argv[1]
if "://" not in url:
    print("localhost 5432")
    raise SystemExit(0)

# Support SQLAlchemy schemes like postgresql+psycopg2://...
scheme, rest = url.split("://", 1)
parsed = urlparse(f"{scheme.split('+', 1)[0]}://{rest}")
host = parsed.hostname or "localhost"
port = parsed.port or 5432
print(f"{host} {port}")
PY
    )

    local check_cmd
    check_cmd='import socket,sys; socket.create_connection((sys.argv[1], int(sys.argv[2])), timeout=1).close()'

    if python3 -c "$check_cmd" "$DB_HOST" "$DB_PORT" >/dev/null 2>&1; then
        echo "Database preflight: reachable at ${DB_HOST}:${DB_PORT}."
        return
    fi

    echo "Database preflight: cannot connect to ${DB_HOST}:${DB_PORT}."

    # For local development defaults, attempt to auto-start bundled PostgreSQL.
    if [ "$DB_HOST" = "localhost" ] && [ "$DB_PORT" = "5432" ] && command -v docker >/dev/null 2>&1; then
        if [ -f "docker-compose.yml" ]; then
            echo "Attempting to start local PostgreSQL via docker compose (service: db)..."
            docker compose up -d db || true
        fi
    fi

    for _ in {1..20}; do
        if python3 -c "$check_cmd" "$DB_HOST" "$DB_PORT" >/dev/null 2>&1; then
            echo "Database preflight: reachable at ${DB_HOST}:${DB_PORT}."
            return
        fi
        sleep 1
    done

    echo "Error: PostgreSQL is unavailable at ${DB_HOST}:${DB_PORT}."
    echo "Run: docker compose up -d db"
    echo "Or set DATABASE_URL/POSTGRES_URL to a reachable database."
    exit 1
}

check_database

# Backend dependency management
setup_backend() {
    if [ "$SKIP_INSTALL" = true ]; then
        echo "Skipping backend installation..."
        return
    fi

    echo "Setting up backend..."
    cd backend
    if [ ! -d ".venv" ]; then
        echo "Creating virtual environment..."
        python3 -m venv .venv
    fi
    
    source .venv/bin/activate
    if [ -f "requirements.txt" ]; then
        echo "Installing backend dependencies..."
        pip install -r requirements.txt
    else
        echo "Warning: backend/requirements.txt not found."
    fi
    cd ..
}

# Frontend dependency management
setup_frontend() {
    if [ "$SKIP_INSTALL" = true ]; then
        echo "Skipping frontend installation..."
        return
    fi

    echo "Setting up frontend..."
    cd frontend
    if [ ! -d "node_modules" ]; then
        echo "Installing frontend dependencies..."
        npm install
    else
        echo "frontend/node_modules already exists. Skipping npm install."
    fi
    cd ..
}

setup_backend
setup_frontend

# Cleanup function for graceful shutdown
cleanup() {
    echo ""
    echo "Stopping services..."
    if [ -n "$BACKEND_PID" ]; then
        kill $BACKEND_PID 2>/dev/null || true
    fi
    if [ -n "$FRONTEND_PID" ]; then
        kill $FRONTEND_PID 2>/dev/null || true
    fi
    echo "Services stopped."
    exit 0
}

# Trap SIGINT (Ctrl+C)
trap cleanup SIGINT

# Start Backend
start_backend() {
    echo -e "\033[0;34m[Backend]\033[0m Starting on port $BACKEND_PORT..."
    cd backend
    if [ -f ".venv/bin/activate" ]; then
        source .venv/bin/activate
    else
        echo -e "\033[0;31m[Backend]\033[0m Warning: .venv/bin/activate not found. Attempting to run without venv."
    fi
    # Use a subshell to prefix output
    python3 -m uvicorn src.app:app --reload --port "$BACKEND_PORT" 2>&1 | sed "s/^/$(echo -e '\033[0;34m[Backend]\033[0m ') /" &
    BACKEND_PID=$!
    cd ..
}

# Start Frontend
start_frontend() {
    echo -e "\033[0;32m[Frontend]\033[0m Starting on port $FRONTEND_PORT..."
    cd frontend
    # Use a subshell to prefix output
    npm run dev -- --port "$FRONTEND_PORT" 2>&1 | sed "s/^/$(echo -e '\033[0;32m[Frontend]\033[0m ') /" &
    FRONTEND_PID=$!
    cd ..
}

start_backend
start_frontend

echo "Services are running. Press Ctrl+C to stop."
wait
