#!/bin/bash

# Production Deployment Script for Reports Dashboard
# =================================================
# This script handles production deployment with proper error handling,
# logging, and rollback capabilities.

set -e  # Exit on any error

# Configuration
PROJECT_NAME="branch-system"
DEPLOY_USER="deploy"
BACKUP_DIR="/var/backups/$PROJECT_NAME"
LOG_FILE="/var/log/$PROJECT_NAME/deploy.log"
VENV_PATH="/opt/$PROJECT_NAME/venv"
PROJECT_PATH="/opt/$PROJECT_NAME"
NGINX_CONFIG="/etc/nginx/sites-available/$PROJECT_NAME"
SYSTEMD_SERVICE="/etc/systemd/system/$PROJECT_NAME.service"

# 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" | tee -a "$LOG_FILE"
}

error() {
    echo -e "${RED}[ERROR]${NC} $1" | tee -a "$LOG_FILE"
    exit 1
}

success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1" | tee -a "$LOG_FILE"
}

warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1" | tee -a "$LOG_FILE"
}

# Check if running as root or with sudo
check_permissions() {
    if [[ $EUID -ne 0 ]]; then
        error "This script must be run as root or with sudo"
    fi
}

# Create necessary directories
setup_directories() {
    log "Setting up directories..."
    
    mkdir -p "$BACKUP_DIR"
    mkdir -p "$(dirname "$LOG_FILE")"
    mkdir -p "$PROJECT_PATH"
    
    # Set proper ownership
    chown -R "$DEPLOY_USER:$DEPLOY_USER" "$PROJECT_PATH"
    chown -R "$DEPLOY_USER:$DEPLOY_USER" "$BACKUP_DIR"
    
    success "Directories created successfully"
}

# Backup current deployment
backup_current() {
    log "Creating backup of current deployment..."
    
    BACKUP_TIMESTAMP=$(date +%Y%m%d_%H%M%S)
    BACKUP_PATH="$BACKUP_DIR/backup_$BACKUP_TIMESTAMP"
    
    if [ -d "$PROJECT_PATH" ]; then
        cp -r "$PROJECT_PATH" "$BACKUP_PATH"
        success "Backup created at $BACKUP_PATH"
    else
        warning "No existing deployment to backup"
    fi
}

# Install system dependencies
install_system_deps() {
    log "Installing system dependencies..."
    
    apt-get update
    apt-get install -y \
        python3 \
        python3-pip \
        python3-venv \
        python3-dev \
        build-essential \
        libpq-dev \
        nginx \
        postgresql \
        postgresql-contrib \
        redis-server \
        supervisor \
        git \
        curl \
        wget \
        unzip
    
    success "System dependencies installed"
}

# Setup Python virtual environment
setup_venv() {
    log "Setting up Python virtual environment..."
    
    if [ ! -d "$VENV_PATH" ]; then
        python3 -m venv "$VENV_PATH"
        chown -R "$DEPLOY_USER:$DEPLOY_USER" "$VENV_PATH"
    fi
    
    # Activate virtual environment and install requirements
    source "$VENV_PATH/bin/activate"
    pip install --upgrade pip
    pip install -r requirements_reports.txt
    
    success "Virtual environment setup complete"
}

# Setup database
setup_database() {
    log "Setting up database..."
    
    # Create database user and database (PostgreSQL)
    sudo -u postgres psql -c "CREATE USER $PROJECT_NAME WITH PASSWORD 'secure_password';" || true
    sudo -u postgres psql -c "CREATE DATABASE ${PROJECT_NAME}_db OWNER $PROJECT_NAME;" || true
    sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE ${PROJECT_NAME}_db TO $PROJECT_NAME;" || true
    
    success "Database setup complete"
}

# Deploy application code
deploy_code() {
    log "Deploying application code..."
    
    # Copy application files
    cd "$PROJECT_PATH"
    
    # Run migrations
    source "$VENV_PATH/bin/activate"
    python manage.py migrate --noinput
    python manage.py collectstatic --noinput
    
    # Create admin user if it doesn't exist
    python manage.py create_admin || true
    
    # Setup registration fees
    python manage.py setup_registration_fees || true
    
    success "Application code deployed"
}

# Configure Nginx
setup_nginx() {
    log "Configuring Nginx..."
    
    cat > "$NGINX_CONFIG" << EOF
server {
    listen 80;
    server_name your-domain.com www.your-domain.com;
    
    location /static/ {
        alias $PROJECT_PATH/staticfiles/;
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
    
    location /media/ {
        alias $PROJECT_PATH/media/;
        expires 1y;
        add_header Cache-Control "public";
    }
    
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
        
        # Timeout settings
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
    
    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;
    
    # Gzip compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
}
EOF
    
    # Enable site
    ln -sf "$NGINX_CONFIG" "/etc/nginx/sites-enabled/"
    nginx -t
    systemctl reload nginx
    
    success "Nginx configured"
}

# Setup systemd service
setup_systemd() {
    log "Setting up systemd service..."
    
    cat > "$SYSTEMD_SERVICE" << EOF
[Unit]
Description=$PROJECT_NAME Django Application
After=network.target postgresql.service redis.service

[Service]
Type=exec
User=$DEPLOY_USER
Group=$DEPLOY_USER
WorkingDirectory=$PROJECT_PATH
Environment=PATH=$VENV_PATH/bin
ExecStart=$VENV_PATH/bin/gunicorn --workers 3 --bind 127.0.0.1:8000 branch_system.wsgi:application
ExecReload=/bin/kill -s HUP \$MAINPID
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF
    
    systemctl daemon-reload
    systemctl enable "$PROJECT_NAME"
    systemctl start "$PROJECT_NAME"
    
    success "Systemd service configured"
}

# Setup SSL with Let's Encrypt (optional)
setup_ssl() {
    log "Setting up SSL certificate..."
    
    # Install certbot
    apt-get install -y certbot python3-certbot-nginx
    
    # Get certificate (replace with your domain)
    # certbot --nginx -d your-domain.com -d www.your-domain.com --non-interactive --agree-tos -m admin@your-domain.com
    
    warning "SSL setup skipped - configure manually with your domain"
}

# Setup monitoring
setup_monitoring() {
    log "Setting up monitoring..."
    
    # Create log rotation
    cat > "/etc/logrotate.d/$PROJECT_NAME" << EOF
$LOG_FILE {
    daily
    missingok
    rotate 52
    compress
    delaycompress
    notifempty
    create 644 $DEPLOY_USER $DEPLOY_USER
}
EOF
    
    # Setup basic health check
    cat > "$PROJECT_PATH/health_check.py" << EOF
#!/usr/bin/env python
import os
import sys
import django
from django.conf import settings

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'branch_system.settings')
django.setup()

from django.db import connection
from django.core.cache import cache

def check_database():
    try:
        with connection.cursor() as cursor:
            cursor.execute("SELECT 1")
        return True
    except:
        return False

def check_cache():
    try:
        cache.set('health_check', 'ok', 30)
        return cache.get('health_check') == 'ok'
    except:
        return False

if __name__ == '__main__':
    db_ok = check_database()
    cache_ok = check_cache()
    
    if db_ok and cache_ok:
        print("OK")
        sys.exit(0)
    else:
        print(f"FAIL - DB: {db_ok}, Cache: {cache_ok}")
        sys.exit(1)
EOF
    
    chmod +x "$PROJECT_PATH/health_check.py"
    
    success "Monitoring setup complete"
}

# Run deployment tests
run_tests() {
    log "Running deployment tests..."
    
    cd "$PROJECT_PATH"
    source "$VENV_PATH/bin/activate"
    
    # Run Django checks
    python manage.py check --deploy
    
    # Test database connection
    python manage.py shell -c "from django.db import connection; connection.ensure_connection()"
    
    # Test critical URLs
    python manage.py shell -c "
from django.test import Client
c = Client()
responses = [
    c.get('/reports/'),
    c.get('/reports/loans-due/'),
    c.get('/reports/delinquent-loans/'),
]
for r in responses:
    assert r.status_code in [200, 302], f'Failed with status {r.status_code}'
print('All tests passed')
"
    
    success "All tests passed"
}

# Main deployment function
main() {
    log "Starting production deployment of $PROJECT_NAME"
    
    check_permissions
    setup_directories
    backup_current
    install_system_deps
    setup_venv
    setup_database
    deploy_code
    setup_nginx
    setup_systemd
    setup_monitoring
    run_tests
    
    success "Production deployment completed successfully!"
    
    log "Deployment Summary:"
    log "- Application: $PROJECT_PATH"
    log "- Virtual Environment: $VENV_PATH"
    log "- Nginx Config: $NGINX_CONFIG"
    log "- Systemd Service: $SYSTEMD_SERVICE"
    log "- Logs: $LOG_FILE"
    log "- Backups: $BACKUP_DIR"
    
    log "Next steps:"
    log "1. Configure your domain in Nginx"
    log "2. Setup SSL certificate with certbot"
    log "3. Configure environment variables"
    log "4. Setup monitoring and alerting"
    log "5. Test all functionality"
}

# Run main function
main "$@"