from __future__ import annotations

import asyncio
import importlib
import unittest
from unittest.mock import AsyncMock, patch

rlm_module = importlib.import_module("rlm")


class RlmModelInfoTest(unittest.TestCase):
    def test_model_info_reports_pinned_metadata(self) -> None:
        host_request = AsyncMock(
            return_value={
                "id": "gemini-3.8-flash-low",
                "provider": "google-antigravity",
                "contextWindow": 1_050_000,
                "payloadCeiling": 945_000,
                "maxTokens": 65536,
                "reasoning": True,
            }
        )

        with patch.object(rlm_module, "host_request", host_request):
            info = asyncio.run(rlm_module.rlm.model_info())

        self.assertIsNotNone(info)
        self.assertEqual(info.id, "gemini-3.8-flash-low")
        self.assertEqual(info.provider, "google-antigravity")
        self.assertEqual(info.context_window, 1_050_000)
        self.assertEqual(info.payload_ceiling, 945_000)
        self.assertEqual(info.max_tokens, 65536)
        self.assertTrue(info.reasoning)
        self.assertEqual(host_request.await_args.args, ("rlm.model_info", {}))

    def test_model_info_passes_an_explicit_model_id(self) -> None:
        host_request = AsyncMock(return_value={"id": "other", "contextWindow": 200_000})

        with patch.object(rlm_module, "host_request", host_request):
            info = asyncio.run(rlm_module.rlm.get_model_info("other"))

        self.assertIsNotNone(info)
        self.assertEqual(host_request.await_args.args, ("rlm.model_info", {"model": "other"}))

    def test_model_info_is_none_when_the_host_reports_an_error(self) -> None:
        host_request = AsyncMock(return_value={"error": "No model specified or active"})

        with patch.object(rlm_module, "host_request", host_request):
            info = asyncio.run(rlm_module.rlm.model_info())

        self.assertIsNone(info)

    def test_model_info_keys_are_optional(self) -> None:
        # Negative control: a payload missing every optional key yields None fields
        # rather than raising or inventing numbers.
        host_request = AsyncMock(return_value={"id": "bare"})

        with patch.object(rlm_module, "host_request", host_request):
            info = asyncio.run(rlm_module.rlm.model_info())

        self.assertIsNotNone(info)
        self.assertEqual(info.id, "bare")
        self.assertIsNone(info.context_window)
        self.assertIsNone(info.payload_ceiling)
        self.assertIsNone(info.max_tokens)
        self.assertIsNone(info.reasoning)


if __name__ == "__main__":
    unittest.main()
