#!/usr/bin/env python3
"""Serve the POC files.

navigator.credentials requires a secure context. Two options:

  1) (recommended for Android) Serve plain HTTP and port-forward localhost:
       python3 server.py --port 8080
       adb reverse tcp:8080 tcp:8080
       # on device: open http://localhost:8080/poc.html  (localhost == secure)

  2) Serve HTTPS with a self-signed cert (Chrome will warn; proceed via
     interstitial). Note: ThirdPartyCredentialManagerImpl::Get() bails out if
     net::IsCertStatusError() is true, so for the get() path use option (1)
     or install the cert as a trusted root on the device.
       python3 server.py --https --port 8443
"""

import argparse
import http.server
import os
import ssl
import subprocess
import sys
import tempfile


class Handler(http.server.SimpleHTTPRequestHandler):
    def __init__(self, *a, **kw):
        super().__init__(*a, directory=os.path.dirname(os.path.abspath(__file__)),
                         **kw)

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


def make_self_signed():
    d = tempfile.mkdtemp()
    key = os.path.join(d, 'key.pem')
    crt = os.path.join(d, 'crt.pem')
    subprocess.check_call([
        'openssl', 'req', '-x509', '-newkey', 'rsa:2048', '-nodes',
        '-keyout', key, '-out', crt, '-days', '7',
        '-subj', '/CN=poc.local',
    ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    return key, crt


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

    httpd = http.server.ThreadingHTTPServer((args.bind, args.port), Handler)

    if args.https:
        key, crt = make_self_signed()
        ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
        ctx.load_cert_chain(certfile=crt, keyfile=key)
        httpd.socket = ctx.wrap_socket(httpd.socket, server_side=True)
        scheme = 'https'
    else:
        scheme = 'http'

    print(f'Serving on {scheme}://{args.bind}:{args.port}/poc.html',
          file=sys.stderr)
    if not args.https:
        print('  For Android: adb reverse tcp:%d tcp:%d  then open '
              'http://localhost:%d/poc.html' % (args.port, args.port, args.port),
              file=sys.stderr)
    httpd.serve_forever()


if __name__ == '__main__':
    main()
