from __future__ import annotations

from pathlib import Path
from typing import Any

import httpx


class HttpTool:
    def __init__(self, cache_dir: Path) -> None:
        self._cache = cache_dir
        self._cache.mkdir(parents=True, exist_ok=True)

    async def request(
        self,
        method: str,
        url: str,
        *,
        headers: dict[str, str] | None = None,
        json_body: dict[str, Any] | None = None,
        data: str | None = None,
        timeout_sec: float = 60.0,
    ) -> dict[str, Any]:
        async with httpx.AsyncClient(timeout=timeout_sec) as client:
            kw: dict[str, Any] = {
                "method": method.upper(),
                "url": url,
                "headers": headers,
            }
            if json_body is not None:
                kw["json"] = json_body
            elif data is not None:
                kw["content"] = data.encode("utf-8")
            resp = await client.request(**kw)
        text = resp.text[:500_000]
        return {
            "ok": resp.is_success,
            "status_code": resp.status_code,
            "headers": dict(resp.headers),
            "text": text,
            "truncated": len(resp.text) > len(text),
        }

    async def download(
        self, url: str, filename: str | None = None, timeout_sec: float = 120.0
    ) -> dict[str, Any]:
        async with httpx.AsyncClient(timeout=timeout_sec) as client:
            resp = await client.get(url)
            resp.raise_for_status()
            name = filename or url.split("/")[-1][:200] or "download.bin"
            dest = self._cache / name
            dest.write_bytes(resp.content)
        return {"ok": True, "path": str(dest), "bytes": len(resp.content)}
