# server_ssl.py
import asyncio
import ssl
from aioquic.asyncio import serve
from aioquic.asyncio.protocol import QuicConnectionProtocol
from aioquic.h3.connection import H3Connection
from aioquic.h3.events import HeadersReceived
from aioquic.quic.configuration import QuicConfiguration
from aioquic.quic.events import ProtocolNegotiated


class HttpServerProtocol(QuicConnectionProtocol):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._http = None

    def quic_event_received(self, event):
        if isinstance(event, ProtocolNegotiated) and event.alpn_protocol == "h3":
            self._http = H3Connection(self._quic)

        if self._http:
            for http_event in self._http.handle_event(event):
                if isinstance(http_event, HeadersReceived):
                    self._http.send_headers(http_event.stream_id, [(b":status", b"200")])
                    self._http.send_data(http_event.stream_id, b"Hello QUIC!", end_stream=True)
                    self.transmit()


def create_ssl_context():
    """Erstellt einen SSL-Context mit allen QUIC-Cipher-Suites"""
    context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
    context.minimum_version = ssl.TLSVersion.TLSv1_3  # QUIC benötigt TLS 1.3
    context.load_cert_chain("cert.pem", "key.pem")
    
    # Cipher-Suites für TLS 1.3 (wird von OpenSSL automatisch gesetzt)
    # TLS 1.3 verwendet: AES-128-GCM, AES-256-GCM, ChaCha20-Poly1305, AES-128-CCM
#    context.set_ciphers("TLS13-AES-128-GCM-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-CCM-SHA256")
    context.set_ciphers("TLS13-AES-128-GCM-SHA256:TLS13-AES-256-GCM-SHA384")
    return context


async def main():
    config = QuicConfiguration(is_client=False, alpn_protocols=["h3"])
    config.load_cert_chain("cert.pem", "key.pem")
    
    # Zusätzlich explizit TLS 1.3 erzwingen
    config.verify_mode = ssl.CERT_NONE
    
    print("Starting HTTP/3 server on localhost:4433...")
    print("Enforcing TLS 1.3 with all QUIC cipher suites")
    
    server = await serve("localhost", 4433, configuration=config, create_protocol=HttpServerProtocol)
    
    print("Server running. Test with: curl --http3 https://localhost:4433/ -k")
    
    try:
        await asyncio.Future()
    except KeyboardInterrupt:
        server.close()
        await server.wait_closed()


if __name__ == "__main__":
    asyncio.run(main())
