#!/usr/bin/env python3
"""
HTTP server for the IWA tabs.move bypass POC.

Serves the dev-mode Isolated Web App with the COOP/COEP/CORP headers that
the IWA installer requires, and accepts a JSON result report from the
extension at POST /report (written to ./poc-result.json and echoed to
stderr so the runner can capture it).
"""
import http.server
import json
import os
import socketserver
import sys

PORT = 8765
ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "iwa-app")
RESULT_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                           "poc-result.json")
IWA_URL_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                            "iwa-url.txt")


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

    def end_headers(self):
        # IWA dev-proxy requires cross-origin-isolated responses.
        self.send_header("Cross-Origin-Opener-Policy", "same-origin")
        self.send_header("Cross-Origin-Embedder-Policy", "require-corp")
        self.send_header("Cross-Origin-Resource-Policy", "same-origin")
        self.send_header("Access-Control-Allow-Origin", "*")
        super().end_headers()

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

    def do_GET(self):
        if self.path.split("?", 1)[0] == "/iwa-url":
            body = b""
            if os.path.exists(IWA_URL_PATH):
                with open(IWA_URL_PATH, "rb") as fh:
                    body = fh.read().strip()
            self.send_response(200)
            self.send_header("Content-Type", "text/plain")
            self.send_header("Content-Length", str(len(body)))
            self.end_headers()
            self.wfile.write(body)
            return
        return super().do_GET()

    def do_OPTIONS(self):
        self.send_response(200)
        self.send_header("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
        self.send_header("Access-Control-Allow-Headers", "*")
        self.end_headers()

    def do_POST(self):
        if self.path == "/report":
            length = int(self.headers.get("Content-Length", "0"))
            body = self.rfile.read(length).decode("utf-8", "replace")
            try:
                data = json.loads(body)
                pretty = json.dumps(data, indent=2)
            except Exception:
                pretty = body
            with open(RESULT_PATH, "w") as fh:
                fh.write(pretty)
            print("\n===== POC RESULT =====", file=sys.stderr)
            print(pretty, file=sys.stderr)
            print("===== END RESULT =====\n", file=sys.stderr)
            sys.stderr.flush()
            self.send_response(200)
            self.end_headers()
            self.wfile.write(b"ok")
            return
        self.send_response(404)
        self.end_headers()

    def log_message(self, fmt, *args):
        sys.stderr.write("[iwa-server] %s\n" % (fmt % args))


class ReusableTCPServer(socketserver.TCPServer):
    allow_reuse_address = True


if __name__ == "__main__":
    with ReusableTCPServer(("127.0.0.1", PORT), Handler) as httpd:
        print(f"[iwa-server] serving {ROOT} on http://127.0.0.1:{PORT}/",
              file=sys.stderr)
        sys.stderr.flush()
        httpd.serve_forever()
