"""
Passenger WSGI entry point for FastAPI application.
This file is used by cPanel's Passenger to serve the FastAPI application.
"""

import sys
import os
from pathlib import Path

project_dir = os.path.dirname(os.path.abspath(__file__))
if project_dir not in sys.path:
    sys.path.insert(0, project_dir)

# Load environment variables from .env file if it exists
env_file = Path(project_dir) / ".env"
if env_file.exists():
    try:
        from dotenv import load_dotenv
        load_dotenv(env_file)
    except ImportError:
        pass

# Set environment to production if not already set
os.environ.setdefault('ENVIRONMENT', 'production')

from app.main import app

# Simple ASGI to WSGI adapter
import asyncio

class SimpleASGItoWSGI:
    def __init__(self, asgi_app):
        self.asgi_app = asgi_app
    
    def __call__(self, environ, start_response):
        # Get or create event loop
        try:
            loop = asyncio.get_event_loop()
        except RuntimeError:
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
        
        # Read request body from WSGI
        content_length = int(environ.get('CONTENT_LENGTH', 0))
        request_body = b''
        if content_length > 0:
            request_body = environ['wsgi.input'].read(content_length)
        
        # Build ASGI scope from WSGI environ
        # IMPORTANT: ASGI headers MUST be lowercase (per ASGI spec)
        headers = []
        for key, value in environ.items():
            if key.startswith('HTTP_'):
                # Convert HTTP_AUTHORIZATION to authorization (lowercase, as required by ASGI)
                header_name = key[5:].replace('_', '-').lower()
                headers.append((header_name.encode(), value.encode()))
        
        # Add Content-Type header if present (not prefixed with HTTP_ in WSGI)
        content_type = environ.get('CONTENT_TYPE')
        if content_type:
            headers.append((b'content-type', content_type.encode()))
        
        # Add Content-Length header if present
        if content_length > 0:
            headers.append((b'content-length', str(content_length).encode()))
        
        scope = {
            'type': 'http',
            'method': environ['REQUEST_METHOD'],
            'path': environ['PATH_INFO'],
            'query_string': environ.get('QUERY_STRING', '').encode(),
            'headers': headers,
            'client': (environ.get('REMOTE_ADDR', ''), 0),
            'server': (environ.get('SERVER_NAME', ''), int(environ.get('SERVER_PORT', 80))),
            'scheme': environ.get('wsgi.url_scheme', 'http'),
        }
        
        response_status = None
        response_headers = []
        response_body_parts = []
        response_complete = False
        body_sent = False
        
        async def receive():
            nonlocal body_sent
            if not body_sent:
                body_sent = True
                return {'type': 'http.request', 'body': request_body, 'more_body': False}
            return {'type': 'http.request', 'body': b'', 'more_body': False}
        
        async def send(message):
            nonlocal response_status, response_headers, response_complete
            if message['type'] == 'http.response.start':
                # Get status code and status text
                status_code = message['status']
                # Map common status codes to their text
                status_texts = {
                    200: 'OK',
                    201: 'Created',
                    204: 'No Content',
                    400: 'Bad Request',
                    401: 'Unauthorized',
                    403: 'Forbidden',
                    404: 'Not Found',
                    405: 'Method Not Allowed',
                    422: 'Unprocessable Entity',
                    500: 'Internal Server Error',
                }
                status_text = status_texts.get(status_code, 'OK')
                response_status = f"{status_code} {status_text}"
                response_headers = [
                    (k.decode() if isinstance(k, bytes) else k, 
                     v.decode() if isinstance(v, bytes) else v)
                    for k, v in message['headers']
                ]
            elif message['type'] == 'http.response.body':
                body = message.get('body', b'')
                if body:
                    response_body_parts.append(body)
                if not message.get('more_body', False):
                    response_complete = True
        
        try:
            # Run the ASGI app
            loop.run_until_complete(self.asgi_app(scope, receive, send))
            
            # Start WSGI response
            if response_status:
                start_response(response_status, response_headers)
            else:
                start_response('200 OK', response_headers)
            
            return response_body_parts
            
        except Exception as e:
            import traceback
            error_msg = f"Error: {str(e)}\n{traceback.format_exc()}"
            status = '500 Internal Server Error'
            headers = [('Content-type', 'text/plain')]
            start_response(status, headers)
            return [error_msg.encode()]

application = SimpleASGItoWSGI(app)
