"""Smoke checks for the public macOS app download path."""

from __future__ import annotations

import re
from dataclasses import dataclass

import httpx


@dataclass
class AppDownloadSmokeResult:
    name: str
    ok: bool
    detail: str


def run_app_download_smoke_check(
    base_url: str,
    *,
    expected_download_url: str | None = None,
) -> list[AppDownloadSmokeResult]:
    """Run smoke checks against the public macOS download path."""
    base = base_url.rstrip("/")
    page_result, download_route = _check_download_page(base)
    results = [
        page_result,
        _check_download_delivery(base, download_route, expected_download_url=expected_download_url),
    ]
    return results


def _check_download_page(base: str) -> tuple[AppDownloadSmokeResult, str | None]:
    try:
        resp = httpx.get(f"{base}/download", timeout=10, follow_redirects=True)
        if resp.status_code != 200:
            return AppDownloadSmokeResult("download_page", False, f"HTTP {resp.status_code}"), None

        match = re.search(r'href="(?P<route>/download/HiveCompute(?:\.dmg|\.app\.zip))"', resp.text)
        if not match:
            return (
                AppDownloadSmokeResult(
                    "download_page",
                    False,
                    "Page rendered but is missing the public app download link",
                ),
                None,
            )

        return AppDownloadSmokeResult("download_page", True, f"OK ({match.group('route')})"), match.group("route")
    except Exception as exc:
        return AppDownloadSmokeResult("download_page", False, f"Connection failed: {exc}"), None


def _check_download_delivery(
    base: str,
    download_route: str | None,
    *,
    expected_download_url: str | None,
) -> AppDownloadSmokeResult:
    route = download_route or "/download/HiveCompute.dmg"
    try:
        resp = httpx.get(
            f"{base}{route}",
            timeout=20,
            follow_redirects=False,
            headers={"Range": "bytes=0-0"},
        )
        if resp.status_code in {200, 206}:
            return _check_download_asset_response(
                resp,
                result_name="download_delivery",
                detail_prefix="OK (served directly)",
            )
        if resp.status_code != 307:
            return AppDownloadSmokeResult(
                "download_delivery",
                False,
                f"Expected 200/206/307, got HTTP {resp.status_code}",
            )

        location = resp.headers.get("location", "").strip()
        if not location:
            return AppDownloadSmokeResult("download_delivery", False, "Redirect missing Location header")

        if expected_download_url and location != expected_download_url:
            return AppDownloadSmokeResult(
                "download_delivery",
                False,
                f"Redirect target mismatch: got {location}, expected {expected_download_url}",
            )

        asset_result = _check_download_asset(location)
        if not asset_result.ok:
            return asset_result

        return AppDownloadSmokeResult("download_delivery", True, f"OK → {location}")
    except Exception as exc:
        return AppDownloadSmokeResult("download_delivery", False, f"Connection failed: {exc}")


def _check_download_asset(url: str) -> AppDownloadSmokeResult:
    try:
        resp = httpx.get(
            url,
            timeout=20,
            follow_redirects=True,
            headers={"Range": "bytes=0-0"},
        )
        return _check_download_asset_response(resp, result_name="download_asset")
    except Exception as exc:
        return AppDownloadSmokeResult("download_asset", False, f"Artifact fetch failed: {exc}")


def _check_download_asset_response(
    resp: httpx.Response,
    *,
    result_name: str,
    detail_prefix: str = "OK",
) -> AppDownloadSmokeResult:
    if resp.status_code not in {200, 206}:
        return AppDownloadSmokeResult(result_name, False, f"Artifact returned HTTP {resp.status_code}")
    content_type = resp.headers.get("content-type", "")
    if "application" not in content_type and "octet-stream" not in content_type and "diskimage" not in content_type:
        return AppDownloadSmokeResult(
            result_name,
            False,
            f"Unexpected content-type: {content_type or 'missing'}",
        )
    return AppDownloadSmokeResult(result_name, True, f"{detail_prefix} ({content_type or 'content-type missing'})")


def format_results(results: list[AppDownloadSmokeResult]) -> str:
    lines = []
    for result in results:
        status = "PASS" if result.ok else "FAIL"
        lines.append(f"  [{status}] {result.name}: {result.detail}")
    passed = sum(1 for result in results if result.ok)
    return f"App download smoke: {passed}/{len(results)} passed\n" + "\n".join(lines)


def troubleshooting_hints(results: list[AppDownloadSmokeResult]) -> list[str]:
    hints: list[str] = []
    failed = {result.name for result in results if not result.ok}
    if "download_page" in failed:
        hints.append(
            "Verify the deployed site still serves /download and that the "
            "public CTA targets the current app artifact route."
        )
    if "download_delivery" in failed:
        hints.append(
            "Check HIVE_APP_DOWNLOAD_URL or HIVE_APP_DOWNLOAD_FILE in the "
            "deployed environment and confirm the current app artifact is reachable."
        )
    if "download_asset" in failed:
        hints.append(
            "Confirm the app artifact exists at the configured download URL and is "
            "publicly reachable without authentication."
        )
    if not hints:
        hints.append("Check the deployed coordinator logs and rerun the smoke after fixing the app download path.")
    return hints
