import json
from pathlib import Path

import httpx

from brp_mcp.spec_loader import SpecLoadError, load_spec_with_cache


class _FakeResponse:
    def __init__(self, payload, status_code=200):
        self._payload = payload
        self.status_code = status_code

    def raise_for_status(self):
        if self.status_code >= 400:
            raise httpx.HTTPStatusError("bad", request=None, response=None)

    def json(self):
        return self._payload


def test_load_spec_remote_success_writes_cache(monkeypatch, tmp_path: Path):
    cache = tmp_path / "openapi.json"
    payload = {"openapi": "3.0.0", "paths": {"/x": {}}}

    class _Client:
        def __init__(self, timeout):
            self.timeout = timeout

        def __enter__(self):
            return self

        def __exit__(self, exc_type, exc, tb):
            return False

        def get(self, url):
            return _FakeResponse(payload)

    monkeypatch.setattr(httpx, "Client", _Client)
    spec, source = load_spec_with_cache("https://example/openapi.json", cache, 5)

    assert source == "remote"
    assert spec == payload
    assert json.loads(cache.read_text(encoding="utf-8")) == payload


def test_load_spec_fallback_to_cache(monkeypatch, tmp_path: Path):
    cache = tmp_path / "openapi.json"
    cached_payload = {"openapi": "3.0.0", "paths": {"/cached": {}}}
    cache.write_text(json.dumps(cached_payload), encoding="utf-8")

    class _Client:
        def __init__(self, timeout):
            self.timeout = timeout

        def __enter__(self):
            return self

        def __exit__(self, exc_type, exc, tb):
            return False

        def get(self, url):
            raise httpx.ConnectError("network down")

    monkeypatch.setattr(httpx, "Client", _Client)
    spec, source = load_spec_with_cache("https://example/openapi.json", cache, 5)

    assert source == "cache"
    assert spec == cached_payload


def test_load_spec_raises_when_no_remote_and_no_cache(monkeypatch, tmp_path: Path):
    cache = tmp_path / "missing/openapi.json"

    class _Client:
        def __init__(self, timeout):
            self.timeout = timeout

        def __enter__(self):
            return self

        def __exit__(self, exc_type, exc, tb):
            return False

        def get(self, url):
            raise httpx.ConnectError("network down")

    monkeypatch.setattr(httpx, "Client", _Client)

    try:
        load_spec_with_cache("https://example/openapi.json", cache, 5)
        assert False, "Expected SpecLoadError"
    except SpecLoadError:
        assert True
