"""Check actual HTTP query values using a temporary loopback server."""
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
import json
from pathlib import Path
import subprocess
import sys
from threading import Thread
from urllib.parse import parse_qsl, urlsplit
from urllib.request import ProxyHandler, build_opener

from build_query import build_url


class Echo(BaseHTTPRequestHandler):
    def do_GET(self):
        assert "#" not in self.path, "URL fragment reached the server"
        parts = urlsplit(self.path)
        data = {"path": parts.path, "pairs": parse_qsl(
            parts.query, keep_blank_values=True, encoding="utf-8", errors="strict",
        )}
        body = json.dumps(data, ensure_ascii=False).encode("utf-8")
        self.send_response(200)
        self.send_header("Content-Type", "application/json; charset=utf-8")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)

    def log_message(self, *args):
        pass


def main():
    expected = [("page", "1"), ("empty", ""), ("tag", "old"),
                ("q", "C++ & Linux/中文"), ("tag", "python"),
                ("tag", "linux"), ("note", "a=b#c"), ("percent", "%2B")]
    with ThreadingHTTPServer(("127.0.0.1", 0), Echo) as server:
        thread = Thread(target=server.serve_forever, daemon=True)
        thread.start()
        try:
            base = f"http://127.0.0.1:{server.server_port}/echo?page=1&empty=&tag=old#local"
            url = build_url(base, expected[3:])
            assert "%2B%2B" in url and "%252B" in url
            # Bypass proxies only for this local test client.
            with build_opener(ProxyHandler({})).open(url, timeout=3) as response:
                assert response.status == 200
                result = json.loads(response.read(65536).decode("utf-8"))
            assert result == {"path": "/echo", "pairs": [list(p) for p in expected]}
            assert url.endswith("#local")
        finally:
            server.shutdown()
            thread.join(timeout=3)
    script = Path(__file__).with_name("build_query.py")
    for arguments, status in [
        (["https://example.com/", "--param", "q=中文"], 0),
        (["file:///tmp/input"], 1),
        (["https://example.com/", "--param", "missing-equals"], 2),
    ]:
        run = subprocess.run([sys.executable, str(script), *arguments],
                             capture_output=True, text=True, timeout=3)
        assert run.returncode == status, run
        assert bool(run.stdout) == (status == 0), run
        assert bool(run.stderr) == (status != 0), run
    print("OK: HTTP round trip, duplicate/blank values, fragment, and CLI exits")


if __name__ == "__main__":
    main()
