#
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.

"""
Example WSGI application demonstrating HTTP/2 with gevent worker.

This application showcases various HTTP/2 features including:
- Basic request/response handling
- Large file transfers (streaming)
- Concurrent requests (multiplexing)
- Server push simulation
"""

import json
import time


def app(environ, start_response):
    """WSGI application for HTTP/2 demonstration."""
    path = environ.get('PATH_INFO', '/')
    method = environ.get('REQUEST_METHOD', 'GET')

    # Root endpoint
    if path == '/':
        body = b'Hello from HTTP/2 with Gevent!'
        status = '200 OK'
        content_type = 'text/plain; charset=utf-8'

    # Health check
    elif path == '/health':
        body = b'OK'
        status = '200 OK'
        content_type = 'text/plain'

    # Echo endpoint - returns the request body
    elif path == '/echo':
        content_length = int(environ.get('CONTENT_LENGTH', 0) or 0)
        body = environ['wsgi.input'].read(content_length)
        status = '200 OK'
        content_type = 'application/octet-stream'

    # JSON endpoint - returns request info as JSON
    elif path == '/info':
        info = {
            'method': method,
            'path': path,
            'protocol': environ.get('SERVER_PROTOCOL', 'unknown'),
            'http_version': environ.get('HTTP_VERSION', '1.1'),
            'server': 'gunicorn with gevent + HTTP/2',
            'headers': {
                k: v for k, v in environ.items()
                if k.startswith('HTTP_')
            }
        }
        body = json.dumps(info, indent=2).encode('utf-8')
        status = '200 OK'
        content_type = 'application/json'

    # Large response for testing streaming/flow control
    elif path == '/large':
        # Return 1MB of data
        size = 1024 * 1024
        body = b'X' * size
        status = '200 OK'
        content_type = 'application/octet-stream'

    # Streaming response using generator
    elif path == '/stream':
        def generate():
            for i in range(10):
                yield f'data: chunk {i}\n\n'.encode('utf-8')
                # Small delay to simulate streaming
                time.sleep(0.1)

        start_response('200 OK', [
            ('Content-Type', 'text/event-stream'),
            ('Cache-Control', 'no-cache'),
        ])
        return generate()

    # Concurrent test endpoint with configurable delay
    elif path.startswith('/delay'):
        query = environ.get('QUERY_STRING', '')
        try:
            delay = float(query.split('=')[1]) if '=' in query else 0.5
            delay = min(delay, 5.0)  # Cap at 5 seconds
        except (ValueError, IndexError):
            delay = 0.5

        # Use gevent sleep for cooperative yielding
        try:
            import gevent
            gevent.sleep(delay)
        except ImportError:
            time.sleep(delay)

        body = f'Delayed response after {delay}s'.encode('utf-8')
        status = '200 OK'
        content_type = 'text/plain'

    # HTTP/2 priority information (if available)
    elif path == '/priority':
        priority_info = {
            'weight': environ.get('HTTP2_PRIORITY_WEIGHT', 'N/A'),
            'depends_on': environ.get('HTTP2_PRIORITY_DEPENDS_ON', 'N/A'),
            'exclusive': environ.get('HTTP2_PRIORITY_EXCLUSIVE', 'N/A'),
        }
        body = json.dumps(priority_info, indent=2).encode('utf-8')
        status = '200 OK'
        content_type = 'application/json'

    # 404 for unknown paths
    else:
        body = b'Not Found'
        status = '404 Not Found'
        content_type = 'text/plain'

    response_headers = [
        ('Content-Type', content_type),
        ('Content-Length', str(len(body))),
        ('X-Worker-Type', 'gevent'),
    ]

    start_response(status, response_headers)
    return [body]


# Allow running directly for testing
if __name__ == '__main__':
    from wsgiref.simple_server import make_server
    server = make_server('localhost', 8000, app)
    print('Test server running on http://localhost:8000')
    server.serve_forever()
