#!/bin/bash
# Deployment Script für Synology NAS
# Dieses Script wird auf der Synology NAS ausgeführt

set -e  # Exit on error

# ============================================
# Configuration
# ============================================
PROJECT_DIR="/volume1/docker/laravel-app"
DOCKER_IMAGE="laravel-app"
COMPOSE_FILE="docker-compose.synology.yml"
ENV_FILE=".env.synology"

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

# ============================================
# Helper Functions
# ============================================
log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# ============================================
# Pre-deployment Checks
# ============================================
log_info "Starting deployment process..."

# Check if running on Synology
if [ ! -d "/volume1" ]; then
    log_error "This script should be run on Synology NAS"
    exit 1
fi

# Navigate to project directory
cd "$PROJECT_DIR" || {
    log_error "Project directory not found: $PROJECT_DIR"
    exit 1
}

# Check if Docker is installed
if ! command -v docker &> /dev/null; then
    log_error "Docker is not installed"
    exit 1
fi

# Check if docker-compose is installed
if ! command -v docker-compose &> /dev/null; then
    log_error "docker-compose is not installed"
    exit 1
fi

# ============================================
# Load Docker Image
# ============================================
if [ -f "laravel-app.tar.gz" ]; then
    log_info "Loading Docker image from artifact..."
    gunzip -c laravel-app.tar.gz | docker load

    # Tag the image appropriately
    LOADED_IMAGE=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep laravel-app | head -n1)
    if [ -n "$LOADED_IMAGE" ]; then
        docker tag "$LOADED_IMAGE" "${DOCKER_IMAGE}:latest"
        log_info "Tagged image as ${DOCKER_IMAGE}:latest"
    fi
else
    log_warn "No Docker image artifact found. Using existing image or building..."

    # Check if Dockerfile exists and build if necessary
    if [ -f "Dockerfile" ]; then
        log_info "Building Docker image..."
        docker build -t "${DOCKER_IMAGE}:latest" .
    else
        log_error "Neither Docker artifact nor Dockerfile found"
        exit 1
    fi
fi

# ============================================
# Environment Configuration
# ============================================
if [ ! -f "$ENV_FILE" ]; then
    log_warn "Environment file not found: $ENV_FILE"

    if [ -f ".env.synology.example" ]; then
        log_info "Copying from .env.synology.example..."
        cp .env.synology.example "$ENV_FILE"
        log_warn "⚠️  Please configure $ENV_FILE with your settings!"
    else
        log_error "No environment configuration found"
        exit 1
    fi
fi

# ============================================
# Backup Current Deployment
# ============================================
log_info "Creating backup of current deployment..."

BACKUP_DIR="/volume1/docker/backups/laravel-app"
mkdir -p "$BACKUP_DIR"

TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/backup_${TIMESTAMP}.tar.gz"

# Backup database if container is running
if docker ps --format '{{.Names}}' | grep -q "laravel_postgres"; then
    log_info "Backing up PostgreSQL database..."
    docker exec laravel_postgres pg_dump -U ingest_user ingest_db > "$BACKUP_DIR/db_${TIMESTAMP}.sql"
fi

# Keep only last 5 backups
log_info "Cleaning old backups (keeping last 5)..."
ls -t "$BACKUP_DIR"/db_*.sql 2>/dev/null | tail -n +6 | xargs -r rm

# ============================================
# Stop Current Containers
# ============================================
log_info "Stopping current containers..."

if [ -f "$COMPOSE_FILE" ]; then
    docker-compose -f "$COMPOSE_FILE" down || log_warn "No containers to stop"
else
    log_warn "Compose file not found: $COMPOSE_FILE"
fi

# ============================================
# Clean up old images (optional)
# ============================================
log_info "Cleaning up old Docker images..."
docker image prune -f

# ============================================
# Start New Deployment
# ============================================
log_info "Starting new deployment..."

if [ ! -f "$COMPOSE_FILE" ]; then
    log_error "Docker Compose file not found: $COMPOSE_FILE"
    exit 1
fi

# Pull/use latest images and start services
docker-compose -f "$COMPOSE_FILE" up -d --build

# ============================================
# Wait for Services to Start
# ============================================
log_info "Waiting for services to start..."
sleep 10

# Check if containers are running
if ! docker ps --format '{{.Names}}' | grep -q "laravel_app"; then
    log_error "Laravel app container failed to start"

    # Show logs
    log_info "Container logs:"
    docker-compose -f "$COMPOSE_FILE" logs --tail=50

    # Rollback
    log_warn "Attempting rollback..."
    docker-compose -f "$COMPOSE_FILE" down
    exit 1
fi

# ============================================
# Post-deployment Tasks
# ============================================
log_info "Running post-deployment tasks..."

# Wait for database to be ready
log_info "Waiting for database to be ready..."
sleep 5

# Run migrations
log_info "Running database migrations..."
docker exec laravel_app php artisan migrate --force || log_warn "Migrations failed"

# Clear caches
log_info "Clearing caches..."
docker exec laravel_app php artisan cache:clear || log_warn "Cache clear failed"
docker exec laravel_app php artisan config:clear || log_warn "Config clear failed"
docker exec laravel_app php artisan view:clear || log_warn "View clear failed"

# Optimize
log_info "Optimizing application..."
docker exec laravel_app php artisan config:cache || log_warn "Config cache failed"
docker exec laravel_app php artisan route:cache || log_warn "Route cache failed"
docker exec laravel_app php artisan view:cache || log_warn "View cache failed"

# ============================================
# Health Check
# ============================================
log_info "Performing health check..."

MAX_RETRIES=30
RETRY_COUNT=0
HEALTH_CHECK_URL="http://localhost:8080"

while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
    if curl -f -s "$HEALTH_CHECK_URL" > /dev/null 2>&1; then
        log_info "✅ Application is healthy!"
        break
    fi

    log_info "⏳ Waiting for application... ($RETRY_COUNT/$MAX_RETRIES)"
    sleep 5
    RETRY_COUNT=$((RETRY_COUNT + 1))
done

if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then
    log_error "Health check failed after $MAX_RETRIES attempts"

    # Show recent logs
    log_info "Recent application logs:"
    docker-compose -f "$COMPOSE_FILE" logs --tail=100

    exit 1
fi

# ============================================
# Display Status
# ============================================
log_info "Deployment completed successfully! 🚀"
log_info "Container status:"
docker-compose -f "$COMPOSE_FILE" ps

log_info ""
log_info "==================================="
log_info "Application URL: http://$(hostname -I | awk '{print $1}'):8080"
log_info "==================================="
log_info ""
log_info "Useful commands:"
log_info "  - View logs:      docker-compose -f $COMPOSE_FILE logs -f"
log_info "  - Restart:        docker-compose -f $COMPOSE_FILE restart"
log_info "  - Stop:           docker-compose -f $COMPOSE_FILE down"
log_info "  - Shell access:   docker exec -it laravel_app sh"

# ============================================
# Cleanup
# ============================================
log_info "Cleaning up deployment artifacts..."
rm -f laravel-app.tar.gz

log_info "Deployment script completed!"
exit 0
