#!/usr/bin/env python3
"""
HTTP server for the share_target.action validation-bypass POC.

Serves an installable PWA at http://localhost:8080/. The manifest contains
a same-origin share_target.action; the patched renderer overwrites it with
a cross-origin URL before sending the manifest to the browser process.

Generates a 256x256 PNG icon on the fly (manifest installability requires an
icon >=144px). Self-contained, no external dependencies.
"""
import http.server
import os
import socketserver
import struct
import zlib

PORT = 8080
HOST = "127.0.0.1"
ROOT = os.path.dirname(os.path.abspath(__file__))


def make_png(w: int, h: int, rgba=(0x33, 0x66, 0xCC, 0xFF)) -> bytes:
    """Build a solid-colour RGBA PNG without external deps."""
    def chunk(typ: bytes, data: bytes) -> bytes:
        return (
            struct.pack(">I", len(data))
            + typ
            + data
            + struct.pack(">I", zlib.crc32(typ + data) & 0xFFFFFFFF)
        )

    sig = b"\x89PNG\r\n\x1a\n"
    ihdr = chunk(b"IHDR", struct.pack(">IIBBBBB", w, h, 8, 6, 0, 0, 0))
    raw = b"\x00" + bytes(rgba) * w  # filter byte + pixel row
    idat = chunk(b"IDAT", zlib.compress(raw * h, 9))
    iend = chunk(b"IEND", b"")
    return sig + ihdr + idat + iend


ICON_PNG = make_png(256, 256)


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

    def end_headers(self):
        # PWA installability and SW registration are tighter on cached files.
        self.send_header("Cache-Control", "no-store")
        # SW served from / so scope is /.
        self.send_header("Service-Worker-Allowed", "/")
        super().end_headers()

    def do_GET(self):
        if self.path.startswith("/icon.png"):
            self.send_response(200)
            self.send_header("Content-Type", "image/png")
            self.send_header("Content-Length", str(len(ICON_PNG)))
            self.end_headers()
            self.wfile.write(ICON_PNG)
            return
        if self.path == "/":
            self.path = "/index.html"
        super().do_GET()

    def guess_type(self, path):
        if path.endswith(".json"):
            return "application/manifest+json"
        if path.endswith(".js"):
            return "application/javascript"
        return super().guess_type(path)


if __name__ == "__main__":
    socketserver.TCPServer.allow_reuse_address = True
    with socketserver.TCPServer((HOST, PORT), Handler) as httpd:
        print(f"[server] http://{HOST}:{PORT}/  (Ctrl-C to stop)")
        httpd.serve_forever()
