#!/usr/bin/env python3
"""Minimal HTTP server for the HostIndexedContentSettings IP-primary /
secondary-domain-wildcard divergence POC.

Serves:
  /poc.html  – top-level page (loaded as http://www.example.test:8080/poc.html)
  /tracker   – third-party subresource (loaded as http://127.0.0.1:9123/tracker)
               Sends a Set-Cookie header so the network service must consult
               cookie content settings with primary_url=127.0.0.1 and
               secondary_url=www.example.test.
"""
import http.server
import socketserver

PORT = 9123

POC_HTML = b"""<!DOCTYPE html>
<html>
<head><title>HostIndexedContentSettings divergence POC</title></head>
<body>
<h3>HostIndexedContentSettings IP-primary / secondary-wildcard divergence</h3>
<pre id="log">Loading IP-literal subresource...</pre>
<script>
const log = m => document.getElementById('log').textContent += '\\n' + m;
log('Top-level: ' + location.origin + ' (secondary_url for cookie checks)');
log('Fetching http://127.0.0.1:9123/tracker (IP-literal primary_url)...');
fetch('http://127.0.0.1:9123/tracker', {credentials: 'include', mode: 'no-cors'})
  .then(() => log('Fetch completed. With the BLOCK rule (*,[*.]example.test) '
                  + 'the cookie content-settings lookup should have returned '
                  + 'BLOCK; the divergence CHECK in the patched build aborts '
                  + 'if the indexed lookup returned nullptr instead.'))
  .catch(e => log('Fetch error: ' + e));
</script>
</body>
</html>
"""


class Handler(http.server.BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path.startswith('/poc.html') or self.path == '/':
            self.send_response(200)
            self.send_header('Content-Type', 'text/html')
            self.send_header('Content-Length', str(len(POC_HTML)))
            self.end_headers()
            self.wfile.write(POC_HTML)
        elif self.path.startswith('/tracker'):
            body = b'ok'
            self.send_response(200)
            self.send_header('Content-Type', 'text/plain')
            # Permissive CORS so the fetch with credentials:'include' isn't
            # blocked before the cookie layer is consulted (the content-settings
            # lookup happens regardless, but this keeps the page log clean).
            self.send_header('Access-Control-Allow-Origin',
                             self.headers.get('Origin', '*'))
            self.send_header('Access-Control-Allow-Credentials', 'true')
            # Triggers CookieSettings::GetCookieSettingInternal in the network
            # service with primary_url=http://127.0.0.1:9123/ and
            # secondary_url=http://www.example.test:8080/.
            self.send_header('Set-Cookie', 'poc=1; Path=/')
            self.send_header('Content-Length', str(len(body)))
            self.end_headers()
            self.wfile.write(body)
        else:
            self.send_response(404)
            self.end_headers()

    def log_message(self, fmt, *args):
        import sys
        sys.stderr.write('[server] %s %s\n' % (self.address_string(), fmt % args))


if __name__ == '__main__':
    socketserver.TCPServer.allow_reuse_address = True
    with socketserver.TCPServer(('127.0.0.1', PORT), Handler) as httpd:
        print(f'Serving on http://127.0.0.1:{PORT}')
        httpd.serve_forever()
