"""Stub minimo de `requests` para tests de enrichers.

Lee el plan de respuesta de `_STUB_REQUESTS_PLAN` (env var con path a un
JSON). Soporta multiples respuestas indexadas por metodo o por sufijo de
URL — la primera coincidencia gana.

Formato del plan:
{
  "default": {"text": "<html>...</html>", "status": 200,
              "headers": {"Content-Type": "text/html; charset=utf-8"}},
  "match": [
    {"contains": "duckduckgo.com", "text": "...", "status": 200},
    {"method": "GET", "contains": "example.com", "text": "..."}
  ]
}
"""
from __future__ import annotations

import json
import os


class Response:
    def __init__(self, text: str = "", status_code: int = 200,
                 headers: dict | None = None, url: str = "",
                 encoding: str = "utf-8") -> None:
        self.text = text
        self.status_code = status_code
        self.headers = headers or {"Content-Type": "text/html; charset=utf-8"}
        self.url = url
        self.encoding = encoding
        self.content = text.encode(encoding, errors="replace")

    def json(self):
        return json.loads(self.text)

    def raise_for_status(self):
        if self.status_code >= 400:
            raise RuntimeError(f"HTTP {self.status_code}")


def _load_plan() -> dict:
    p = os.environ.get("_STUB_REQUESTS_PLAN")
    if not p or not os.path.exists(p):
        return {}
    with open(p, "r", encoding="utf-8") as f:
        return json.load(f)


def _resolve(method: str, url: str) -> Response:
    plan = _load_plan()
    for entry in plan.get("match", []):
        if "method" in entry and entry["method"].upper() != method.upper():
            continue
        needle = entry.get("contains") or ""
        if needle and needle in url:
            return Response(
                text=entry.get("text", ""),
                status_code=int(entry.get("status", 200)),
                headers=entry.get("headers"),
                url=url,
            )
    d = plan.get("default") or {}
    return Response(
        text=d.get("text", ""),
        status_code=int(d.get("status", 200)),
        headers=d.get("headers"),
        url=url,
    )


def get(url, *args, **kwargs):
    return _resolve("GET", url)


def post(url, *args, **kwargs):
    return _resolve("POST", url)


# Compatibilidad con `requests.exceptions.RequestException` si algun
# enricher lo importa en el futuro.
class RequestException(Exception):
    pass


class exceptions:  # noqa: N801
    RequestException = RequestException
    Timeout = RequestException
    ConnectionError = RequestException
