#!/bin/bash

# Unison Service Startup Script
# This script handles the startup of the Unison service with proper error handling and logging

set -e

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Logging function
log() {
    echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] ✓${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] ⚠${NC} $1"
}

log_error() {
    echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ✗${NC} $1"
}

# Configuration
SERVICE_NAME="Unison"
SERVICE_PORT=${PORT:-8010}
SERVICE_HOST=${HOST:-0.0.0.0}
NODE_ENV=${NODE_ENV:-development}
LOG_LEVEL=${LOG_LEVEL:-info}

# External service URLs (set by docker-compose.yml)
TECH_STACK_SELECTOR_URL=${TECH_STACK_SELECTOR_URL:-http://pipeline_tech_stack_selector:8002}
TEMPLATE_MANAGER_URL=${TEMPLATE_MANAGER_URL:-http://pipeline_template_manager:8009}
TEMPLATE_MANAGER_AI_URL=${TEMPLATE_MANAGER_AI_URL:-http://pipeline_template_manager:8013}

# Health check URLs (set by docker-compose.yml)
TECH_STACK_SELECTOR_HEALTH_URL=${TECH_STACK_SELECTOR_HEALTH_URL:-http://pipeline_tech_stack_selector:8002/health}
TEMPLATE_MANAGER_HEALTH_URL=${TEMPLATE_MANAGER_HEALTH_URL:-http://pipeline_template_manager:8009/health}

# Timeouts
REQUEST_TIMEOUT=${REQUEST_TIMEOUT:-30000}
HEALTH_CHECK_TIMEOUT=${HEALTH_CHECK_TIMEOUT:-5000}

# Create logs directory
mkdir -p logs

# Load environment variables from config.env if it exists
if [ -f "config.env" ]; then
    echo "Loading environment variables from config.env..."
    export $(cat config.env | grep -v '^#' | xargs)
fi

# Function to check if a service is healthy
check_service_health() {
    local service_name=$1
    local health_url=$2
    local timeout=${3:-5000}
    
    log "Checking health of $service_name at $health_url..."
    
    if curl -f -s --max-time $((timeout / 1000)) "$health_url" > /dev/null 2>&1; then
        log_success "$service_name is healthy"
        return 0
    else
        log_warning "$service_name is not responding"
        return 1
    fi
}

# Function to wait for external services
wait_for_services() {
    log "Waiting for external services to be available..."
    
    local max_attempts=30
    local attempt=1
    
    while [ $attempt -le $max_attempts ]; do
        log "Attempt $attempt/$max_attempts: Checking external services..."
        
        local tech_stack_healthy=false
        local template_manager_healthy=false
        
        if check_service_health "Tech Stack Selector" "$TECH_STACK_SELECTOR_HEALTH_URL" "$HEALTH_CHECK_TIMEOUT"; then
            tech_stack_healthy=true
        fi
        
        if check_service_health "Template Manager" "$TEMPLATE_MANAGER_HEALTH_URL" "$HEALTH_CHECK_TIMEOUT"; then
            template_manager_healthy=true
        fi
        
        if [ "$tech_stack_healthy" = true ] && [ "$template_manager_healthy" = true ]; then
            log_success "All external services are healthy"
            return 0
        fi
        
        log_warning "Some services are not ready yet. Waiting 10 seconds..."
        sleep 10
        attempt=$((attempt + 1))
    done
    
    log_error "Timeout waiting for external services after $max_attempts attempts"
    log_warning "Starting service anyway - it will handle service unavailability gracefully"
    return 1
}

# Function to validate environment
validate_environment() {
    log "Validating environment configuration..."
    
    # Check Node.js version
    if ! command -v node &> /dev/null; then
        log_error "Node.js is not installed"
        exit 1
    fi
    
    local node_version=$(node --version)
    log_success "Node.js version: $node_version"
    
    # Check if package.json exists
    if [ ! -f "package.json" ]; then
        log_error "package.json not found"
        exit 1
    fi
    
    # Check if node_modules exists
    if [ ! -d "node_modules" ]; then
        log_warning "node_modules not found. Installing dependencies..."
        npm install
    fi
    
    # Check if source directory exists
    if [ ! -d "src" ]; then
        log_error "Source directory 'src' not found"
        exit 1
    fi
    
    # Check if main app file exists
    if [ ! -f "src/app.js" ]; then
        log_error "Main application file 'src/app.js' not found"
        exit 1
    fi
    
    log_success "Environment validation passed"
}

# Function to start the service
start_service() {
    log "Starting $SERVICE_NAME service..."
    
    # Set environment variables
    export NODE_ENV
    export PORT=$SERVICE_PORT
    export HOST=$SERVICE_HOST
    export LOG_LEVEL
    export TECH_STACK_SELECTOR_URL
    export TEMPLATE_MANAGER_URL
    export TEMPLATE_MANAGER_AI_URL
    export TECH_STACK_SELECTOR_HEALTH_URL
    export TEMPLATE_MANAGER_HEALTH_URL
    export REQUEST_TIMEOUT
    export HEALTH_CHECK_TIMEOUT
    
    # Log configuration
    log "Configuration:"
    log "  Service: $SERVICE_NAME"
    log "  Port: $SERVICE_PORT"
    log "  Host: $SERVICE_HOST"
    log "  Environment: $NODE_ENV"
    log "  Log Level: $LOG_LEVEL"
    log "  Tech Stack Selector: $TECH_STACK_SELECTOR_URL"
    log "  Template Manager: $TEMPLATE_MANAGER_URL"
    log "  Template Manager AI: $TEMPLATE_MANAGER_AI_URL"
    
    # Start the service
    log "Starting Node.js application..."
    exec node src/app.js
}

# Function to handle graceful shutdown
cleanup() {
    log "Received shutdown signal. Cleaning up..."
    log_success "$SERVICE_NAME service stopped gracefully"
    exit 0
}

# Set up signal handlers
trap cleanup SIGTERM SIGINT

# Main execution
main() {
    log "Starting $SERVICE_NAME service initialization..."
    
    # Validate environment
    validate_environment
    
    # Wait for external services (non-blocking)
    wait_for_services || true
    
    # Start the service
    start_service
}

# Run main function
main "$@"
