"""custom-html — recipe-specific functional test (Phase 2 P3, ≥2 beyond parity).

nginx maps file extensions to MIME types in its default mime.types config. A working serve emits
`Content-Type: text/html` for `.html` and `text/plain` for `.txt`. A broken/misconfigured serve
(e.g. nginx falling back to `application/octet-stream`, or a wrong mime.types include) would not.
This distinguishes a real working nginx from a generic 200-returner.

Runs in the custom tier against the shared post-install deployment.
"""

from __future__ import annotations

import os
import ssl
import sys
import urllib.request
import uuid

sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "..", "runner"))
from harness import lifecycle  # noqa: E402


def _head(url: str) -> tuple[int, dict[str, str]]:
    """HEAD the URL (no body), return (status, headers)."""
    ctx = ssl.create_default_context()
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE
    req = urllib.request.Request(url, method="GET")  # nginx default config may not allow HEAD on /,
    # but per-file GET always returns headers; we read 0 bytes anyway.
    with urllib.request.urlopen(req, timeout=15, context=ctx) as resp:
        return resp.status, {k.lower(): v for k, v in resp.getheaders()}


def test_content_type_html_and_txt(live_app):
    """Write an .html file AND a .txt file into the served volume, fetch each, assert nginx returns
    the right MIME type for each. Non-vacuous: both files exist with the same bytes — only the
    extension/MIME mapping distinguishes them; a broken MIME config would fail this even if 200."""
    html_name = f"ccci-{uuid.uuid4().hex[:8]}.html"
    txt_name = f"ccci-{uuid.uuid4().hex[:8]}.txt"
    body = "hello"
    for name in (html_name, txt_name):
        lifecycle.exec_in_app(
            live_app, ["sh", "-c", f"printf %s {body} > /usr/share/nginx/html/{name}"]
        )

    s_html, h_html = _head(f"https://{live_app}/{html_name}")
    s_txt, h_txt = _head(f"https://{live_app}/{txt_name}")

    assert s_html == 200, f"html file status {s_html}"
    assert s_txt == 200, f"txt file status {s_txt}"

    ct_html = h_html.get("content-type", "")
    ct_txt = h_txt.get("content-type", "")

    # nginx default: "text/html" for .html and "text/plain" for .txt (may include "; charset=utf-8")
    assert ct_html.startswith("text/html"), (
        f"{html_name} Content-Type={ct_html!r}, expected text/html (nginx MIME config broken?)"
    )
    assert ct_txt.startswith("text/plain"), (
        f"{txt_name} Content-Type={ct_txt!r}, expected text/plain (nginx MIME config broken?)"
    )
