"""Three bounded HTTPX requests through an explicit proxy; no URLs or bodies logged."""

import asyncio
import hashlib
import json
import os
import sys

import httpx

MAX_BODY_BYTES = 65_536


def make_client(proxy_url: str) -> httpx.AsyncClient:
    return httpx.AsyncClient(
        proxy=proxy_url,
        trust_env=False,
        http2=False,
        follow_redirects=False,
        limits=httpx.Limits(max_connections=2, max_keepalive_connections=2),
        timeout=httpx.Timeout(connect=5.0, read=5.0, write=5.0, pool=0.25),
    )


class BodyTooLarge(Exception):
    pass


async def check_proxy(proxy_url: str, target_url: str) -> list[dict]:
    """Use one client for three GETs, admitting at most two at once.

    The deadline includes semaphore waiting, pool waiting and response reading.
    The hash checks repeatability only; the caller must validate useful content.
    TLS verification stays enabled. The target and proxy must be authorized.
    """
    admission = asyncio.Semaphore(2)
    async with make_client(proxy_url) as client:
        async def fetch(request_id: int) -> dict:
            try:
                async with asyncio.timeout(10.0):
                    async with admission:
                        async with client.stream("GET", target_url) as response:
                            response.raise_for_status()
                            digest = hashlib.sha256()
                            count = 0
                            async for chunk in response.aiter_bytes(chunk_size=8192):
                                count += len(chunk)
                                if count > MAX_BODY_BYTES:
                                    raise BodyTooLarge()
                                digest.update(chunk)
                            return {"request": request_id, "status": response.status_code,
                                    "body_bytes": count, "body_sha256": digest.hexdigest()}
            except TimeoutError:
                return {"request": request_id, "error": "OperationDeadline"}
            except (httpx.HTTPError, httpx.InvalidURL, BodyTooLarge) as error:
                return {"request": request_id, "error": type(error).__name__}

        return await asyncio.gather(*(fetch(i) for i in range(1, 4)))


def main() -> int:
    proxy_url = os.environ.get("PROXY_URL")
    target_url = os.environ.get("TARGET_URL")
    if not proxy_url or not target_url:
        print(json.dumps({"error": "Set PROXY_URL and TARGET_URL"}))
        return 2
    try:
        results = asyncio.run(check_proxy(proxy_url, target_url))
    except Exception as error:
        # Exception messages can contain credentials or sensitive request URLs.
        print(json.dumps({"error": type(error).__name__}))
        return 1
    print(json.dumps(results, indent=2))
    return int(any("error" in result for result in results))


if __name__ == "__main__":
    sys.exit(main())
