from __future__ import annotations
import asyncio
import re
from dataclasses import dataclass, field

import httpx


@dataclass
class HttpInfo:
    http1: bool = False
    http1_status: int | None = None
    http2: bool = False
    http3_via_alt_svc: bool = False
    alt_svc: str | None = None
    server: str | None = None
    content_encoding: str | None = None
    valid_http_response: bool = False
    error: str | None = None
    compression_enabled: bool = False


async def probe_http(host: str, port: int, timeout: float = 6.0) -> HttpInfo:
    info = HttpInfo()
    url = f"https://{host}:{port}/" if port != 443 else f"https://{host}/"
    headers = {
        "User-Agent": "nercone-tls-test/1.0",
        "Accept-Encoding": "gzip, deflate, br",
    }
    try:
        async with httpx.AsyncClient(
            timeout=timeout,
            verify=False,
            follow_redirects=False,
            headers=headers,
            http1=True,
            http2=False,
        ) as client:
            resp = await client.get(url)
            info.http1 = True
            info.http1_status = resp.status_code
            info.valid_http_response = True
            info.server = resp.headers.get("server")
            info.alt_svc = resp.headers.get("alt-svc")
            info.content_encoding = resp.headers.get("content-encoding")
            if info.content_encoding:
                info.compression_enabled = True
    except Exception as e:
        info.error = f"http1: {e.__class__.__name__}: {e}"

    try:
        async with httpx.AsyncClient(
            timeout=timeout,
            verify=False,
            follow_redirects=False,
            headers=headers,
            http1=False,
            http2=True,
        ) as client:
            resp = await client.get(url)
            info.http2 = (resp.http_version.upper().startswith("HTTP/2"))
            if info.http2:
                if not info.alt_svc:
                    info.alt_svc = resp.headers.get("alt-svc")
                if not info.server:
                    info.server = resp.headers.get("server")
    except Exception:
        pass

    if info.alt_svc and ("h3=" in info.alt_svc or "h3-" in info.alt_svc):
        info.http3_via_alt_svc = True

    return info
