"""Two availability claims about parley, checked against a running server.

  1. A half-sent request pins a thread for ever. `Handler` sets no `timeout`,
     so `StreamRequestHandler.setup` never calls `settimeout`, and
     `ThreadingHTTPServer` is one thread per *connection* under HTTP/1.1
     keep-alive. With `TasksMax=32` in the unit, 31 of these are the whole
     service.

  2. `do_OPTIONS` answers 204 and writes a two-byte body with it. A 204 is
     bodyless by definition, so a pooled upstream connection keeps the two
     bytes and hands them to whatever is parsed next.
"""

import socket
import tempfile
import threading
import time
from pathlib import Path

from parley import api, wake

HOLD = 25          # seconds to hold the half-sent requests open
N = 6


def main():
    tmp = tempfile.TemporaryDirectory()
    root = Path(tmp.name)
    cfg = wake.WakeConfig(3, 10, root / "wake")
    httpd = api.serve(root / "parley.db", host="127.0.0.1", port=0, wake_cfg=cfg)
    port = httpd.server_address[1]
    threading.Thread(target=httpd.serve_forever, daemon=True).start()
    time.sleep(0.3)

    base = threading.active_count()
    print(f"threads before          : {base}")

    # -- 1. dribble ---------------------------------------------------------
    held = []
    for i in range(N):
        s = socket.create_connection(("127.0.0.1", port), timeout=5)
        s.sendall(b"POST /say HTTP/1.1\r\nHost: x\r\nContent-Length: 100\r\n"
                  b"Content-Type: application/json\r\n\r\n{")
        held.append(s)
    time.sleep(1.0)
    print(f"threads after {N} half-sent: {threading.active_count()}")
    print(f"holding them open for {HOLD}s without sending another byte ...")
    time.sleep(HOLD)
    print(f"threads after {HOLD}s idle  : {threading.active_count()}"
          f"  <- nothing reclaims them")

    # -- 2. the 204 with a body --------------------------------------------
    s = socket.create_connection(("127.0.0.1", port), timeout=5)
    s.sendall(b"OPTIONS /health HTTP/1.1\r\nHost: x\r\n\r\n")
    time.sleep(0.4)
    raw = s.recv(4096)
    print("OPTIONS /health ->", raw.decode("latin-1").replace("\r\n", " | "))
    s.close()

    for s in held:
        s.close()
    httpd.shutdown()
    httpd.server_close()
    tmp.cleanup()


if __name__ == "__main__":
    main()
