#!/usr/bin/env python3
"""
WSGI entry point for Gunicorn
This file is the interface between Gunicorn and your Flask application
"""

import sys
import os
import logging
import redis
import time
from datetime import datetime
from flask import Flask, jsonify

# Configure logging first
logging.basicConfig(
    level=logging.INFO,
    format='[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
    stream=sys.stderr
)

# Add the application directory to path if needed
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

# Redis configuration from environment variables
REDIS_HOST = os.getenv('REDIS_HOST', 'localhost')
REDIS_PORT = int(os.getenv('REDIS_PORT', 6379))
REDIS_PASSWORD = os.getenv('REDIS_PASSWORD', None)

# Initialize Redis client
try:
    redis_client = redis.Redis(
        host=REDIS_HOST,
        port=REDIS_PORT,
        password=REDIS_PASSWORD,
        decode_responses=True,
        socket_connect_timeout=5,
        socket_timeout=5
    )
    # Test connection
    redis_client.ping()
    logging.info(f"✓ Redis connected successfully at {REDIS_HOST}:{REDIS_PORT}")
except Exception as e:
    logging.error(f"✗ Failed to connect to Redis: {e}")
    redis_client = None

# Import Flask app after logging is configured
try:
    from app import app as application
    logging.info("✓ Flask application imported successfully")
except ImportError as e:
    _import_error_msg = str(e)   # save now — Python 3 deletes `e` when except block exits
    logging.error(f"✗ Failed to import Flask application: {_import_error_msg}")
    # Create a minimal app for error reporting
    application = Flask(__name__)
    
    @application.route('/')
    def error_page():
        return jsonify({
            'error': 'Application import failed',
            'message': _import_error_msg,
            'status': 'error'
        }), 500
    
    @application.route('/health')
    def health():
        return jsonify({
            'status': 'error',
            'error': 'Application import failed',
            'redis_status': 'not_initialized'
        }), 500

# Add Redis health check routes
@application.route('/health/redis')
def redis_health():
    """Check Redis connection status"""
    if redis_client is None:
        return jsonify({
            'status': 'disconnected',
            'error': 'Redis client not initialized',
            'redis_host': REDIS_HOST,
            'redis_port': REDIS_PORT,
            'timestamp': datetime.utcnow().isoformat()
        }), 500
    
    try:
        start_time = time.time()
        redis_client.ping()
        response_time = round((time.time() - start_time) * 1000, 2)
        info = redis_client.info()
        
        return jsonify({
            'status': 'connected',
            'redis_host': REDIS_HOST,
            'redis_port': REDIS_PORT,
            'response_time_ms': response_time,
            'redis_version': info.get('redis_version'),
            'uptime_seconds': info.get('uptime_in_seconds'),
            'connected_clients': info.get('connected_clients'),
            'used_memory_human': info.get('used_memory_human'),
            'total_keys': len(redis_client.keys('*')) if redis_client else 0,
            'timestamp': datetime.utcnow().isoformat()
        }), 200
        
    except redis.ConnectionError as e:
        return jsonify({
            'status': 'disconnected',
            'redis_host': REDIS_HOST,
            'redis_port': REDIS_PORT,
            'error': str(e),
            'timestamp': datetime.utcnow().isoformat()
        }), 500
    except Exception as e:
        return jsonify({
            'status': 'error',
            'error': str(e),
            'timestamp': datetime.utcnow().isoformat()
        }), 500

@application.route('/health/redis/jobs')
def redis_jobs_status():
    """Check Redis job queues status"""
    if redis_client is None:
        return jsonify({
            'status': 'disconnected',
            'error': 'Redis client not initialized',
            'timestamp': datetime.utcnow().isoformat()
        }), 500
    
    try:
        redis_client.ping()
        queues = redis_client.smembers('rq:queues')
        queue_stats = {}
        
        for queue in queues:
            queue_key = f'rq:queue:{queue}'
            queue_length = redis_client.llen(queue_key)
            queue_stats[queue] = queue_length
        
        failed_jobs = redis_client.zcard('rq:failed')
        all_keys = redis_client.keys('job:*')
        job_keys = [k for k in all_keys if k.startswith('job:')]
        
        job_status = {}
        for job_key in job_keys[:100]:
            job_data = redis_client.hgetall(job_key)
            if 'status' in job_data:
                status = job_data['status']
                job_status[status] = job_status.get(status, 0) + 1
        
        return jsonify({
            'status': 'connected',
            'queues': queue_stats,
            'failed_jobs': failed_jobs,
            'total_jobs': len(job_keys),
            'job_status_counts': job_status,
            'timestamp': datetime.utcnow().isoformat()
        }), 200
        
    except redis.ConnectionError as e:
        return jsonify({
            'status': 'disconnected',
            'error': str(e),
            'timestamp': datetime.utcnow().isoformat()
        }), 500
    except Exception as e:
        return jsonify({
            'status': 'error',
            'error': str(e),
            'timestamp': datetime.utcnow().isoformat()
        }), 500

@application.route('/health/redis/test')
def redis_test():
    """Test Redis write/read operations"""
    if redis_client is None:
        return jsonify({
            'status': 'failed',
            'error': 'Redis client not initialized',
            'timestamp': datetime.utcnow().isoformat()
        }), 500
    
    try:
        test_key = f'health_check_{int(time.time())}'
        test_value = f'test_{datetime.utcnow().isoformat()}'
        
        start_write = time.time()
        redis_client.set(test_key, test_value, ex=60)
        write_time = round((time.time() - start_write) * 1000, 2)
        
        start_read = time.time()
        read_value = redis_client.get(test_key)
        read_time = round((time.time() - start_read) * 1000, 2)
        
        redis_client.delete(test_key)
        
        return jsonify({
            'status': 'success',
            'write_test': {'success': True, 'time_ms': write_time},
            'read_test': {'success': read_value == test_value, 'value': read_value, 'time_ms': read_time},
            'timestamp': datetime.utcnow().isoformat()
        }), 200
        
    except Exception as e:
        return jsonify({
            'status': 'failed',
            'error': str(e),
            'timestamp': datetime.utcnow().isoformat()
        }), 500

@application.route('/health/all')
def all_health():
    """Comprehensive health check"""
    health_status = {
        'app': 'running',
        'timestamp': datetime.utcnow().isoformat(),
        'checks': {}
    }
    
    if redis_client:
        try:
            start_time = time.time()
            redis_client.ping()
            response_time = round((time.time() - start_time) * 1000, 2)
            health_status['checks']['redis'] = {
                'status': 'connected',
                'host': REDIS_HOST,
                'port': REDIS_PORT,
                'response_time_ms': response_time
            }
        except Exception as e:
            health_status['checks']['redis'] = {'status': 'disconnected', 'error': str(e)}
    else:
        health_status['checks']['redis'] = {'status': 'disconnected', 'error': 'Redis client not initialized'}
    
    all_healthy = all(c.get('status') == 'connected' for c in health_status['checks'].values())
    
    if all_healthy:
        health_status['overall_status'] = 'healthy'
        status_code = 200
    else:
        health_status['overall_status'] = 'critical'
        status_code = 503
    
    return jsonify(health_status), status_code

@application.route('/health/ping')
def ping():
    """Simple ping endpoint for basic health checks"""
    redis_status = False
    if redis_client:
        try:
            redis_status = redis_client.ping()
        except:
            redis_status = False
    
    return jsonify({
        'status': 'ok',
        'timestamp': datetime.utcnow().isoformat(),
        'redis_available': redis_status
    }), 200

# IMPORTANT: Export both 'application' and 'app' for compatibility
# Gunicorn can use either wsgi:application or wsgi:app
app = application

# Log that wsgi.py has been loaded
logging.info("wsgi.py loaded successfully")
logging.info(f"Redis configured for {REDIS_HOST}:{REDIS_PORT}")
logging.info(f"WSGI exports: application and app (both available)")

# For local development — port read from APP_PORT env var, falls back to 6001
if __name__ == "__main__":
    _dev_port = int(os.getenv('APP_PORT', 6001))
    logging.info(f"Starting development server on port {_dev_port}...")
    application.run(host="0.0.0.0", port=_dev_port, debug=True)
