from __future__ import annotations

import importlib
import sys
from types import ModuleType


class _FakeLookup:
    def __init__(self) -> None:
        self.calls = []

    def lookup(self, lat: float, lon: float):
        self.calls.append((lat, lon))
        return {
            "lookup_status": "ok",
            "world_context": {"country": {"iso2": "TW", "name": "Taiwan"}},
        }


class _FakeGlobalLookup:
    init_calls = 0

    @classmethod
    def from_defaults(cls, **kwargs):
        cls.init_calls += 1
        return _FakeLookup()


def _install_fake_cadis_world(module: ModuleType) -> None:
    sys.modules["cadis.world"] = module


def _reload_cadis_modules() -> None:
    for name in ["cadis", "cadis._api", "cadis._manager"]:
        sys.modules.pop(name, None)


def test_lookup_is_lazy_singleton(monkeypatch):
    fake_mod = ModuleType("cadis.world")
    fake_mod.GlobalLookup = _FakeGlobalLookup
    runtime_mod = ModuleType("cadis.runtime")
    runtime_mod.inspect_dataset = lambda dataset_dir: {"state": {"dataset": {"status": "missing"}}}

    _install_fake_cadis_world(fake_mod)
    sys.modules["cadis.runtime"] = runtime_mod
    _reload_cadis_modules()

    cadis = importlib.import_module("cadis")
    assert _FakeGlobalLookup.init_calls == 0

    first = cadis.lookup(25.03, 121.56)
    second = cadis.lookup(35.68, 139.76)

    assert _FakeGlobalLookup.init_calls == 1
    assert first["execution"]["lookup_status"] == "failed"
    assert second["execution"]["lookup_status"] == "failed"


def test_info_has_no_lookup_side_effect(monkeypatch, tmp_path):
    cache_dir = tmp_path / "cadis-cache"
    cache_dir.mkdir()
    (cache_dir / "tw").mkdir()
    (cache_dir / "not-iso").mkdir()
    monkeypatch.setenv("CADIS_CACHE_DIR", str(cache_dir))
    _reload_cadis_modules()

    cadis = importlib.import_module("cadis")
    payload = cadis.info()

    assert payload["schema_version"] == "1"
    assert payload["supported_iso2"] == ["JP", "TW"]
    assert payload["installed_iso2"] == ["TW"]


def test_reason_normalization_runtime_error(monkeypatch):
    class _BrokenGlobalLookup:
        @classmethod
        def from_defaults(cls, **kwargs):
            raise Exception("boom")

    fake_mod = ModuleType("cadis.world")
    fake_mod.GlobalLookup = _BrokenGlobalLookup

    _install_fake_cadis_world(fake_mod)
    _reload_cadis_modules()

    cadis = importlib.import_module("cadis")
    payload = cadis.lookup(25.03, 121.56)

    assert payload["execution"]["lookup_status"] == "failed"
    assert "traceback" not in str(payload).lower()
