#!/usr/bin/env python3
"""
Minimal HTTPS server for the WebXR-Layers RASTERIZER_DISCARD POC.

WebXR (navigator.xr.requestSession) is a powerful feature and requires a
secure context.  On a real Android device you must serve poc.html over
HTTPS (or use chrome://flags#unsafely-treat-insecure-origin-as-secure).

Usage:
    # Plain HTTP (use only with the insecure-origin flag, or via
    # `adb reverse tcp:8080 tcp:8080` + http://localhost:8080/poc.html
    # — localhost is a secure context on Android too):
    python3 server.py

    # HTTPS with a self-signed cert:
    python3 server.py --https
    # then visit https://<host>:8443/poc.html and accept the cert warning.
"""
import argparse
import http.server
import os
import socketserver
import ssl
import subprocess
import sys
import tempfile

ROOT = os.path.dirname(os.path.abspath(__file__))


class Handler(http.server.SimpleHTTPRequestHandler):
    def __init__(self, *a, **kw):
        super().__init__(*a, directory=ROOT, **kw)

    def end_headers(self):
        self.send_header('Cache-Control', 'no-store')
        super().end_headers()


def make_selfsigned(tmpdir):
    cert = os.path.join(tmpdir, 'cert.pem')
    key = os.path.join(tmpdir, 'key.pem')
    subprocess.check_call([
        'openssl', 'req', '-x509', '-newkey', 'rsa:2048', '-nodes',
        '-keyout', key, '-out', cert, '-days', '1', '-subj', '/CN=localhost',
    ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    return cert, key


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument('--port', type=int, default=None)
    ap.add_argument('--https', action='store_true')
    args = ap.parse_args()

    socketserver.TCPServer.allow_reuse_address = True

    if args.https:
        port = args.port or 8443
        tmp = tempfile.mkdtemp()
        cert, key = make_selfsigned(tmp)
        httpd = socketserver.TCPServer(('0.0.0.0', port), Handler)
        ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
        ctx.load_cert_chain(cert, key)
        httpd.socket = ctx.wrap_socket(httpd.socket, server_side=True)
        print(f'serving HTTPS on 0.0.0.0:{port} -> https://<host>:{port}/poc.html',
              file=sys.stderr)
    else:
        port = args.port or 8080
        httpd = socketserver.TCPServer(('0.0.0.0', port), Handler)
        print(f'serving HTTP on 0.0.0.0:{port} -> http://localhost:{port}/poc.html',
              file=sys.stderr)
        print('NOTE: WebXR requires a secure context. Either use the HTTPS mode,',
              file=sys.stderr)
        print('      or `adb reverse tcp:8080 tcp:8080` and load http://localhost:8080/',
              file=sys.stderr)
        print('      (localhost is treated as secure), or set the',
              file=sys.stderr)
        print('      chrome://flags#unsafely-treat-insecure-origin-as-secure flag.',
              file=sys.stderr)

    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass


if __name__ == '__main__':
    main()
