"""Tests for model tools."""

from unittest.mock import MagicMock, patch

import pytest

from tests.conftest import MockMCP


@pytest.fixture
def mcp():
    m = MockMCP()
    from kaggle_mcp import models
    models.register(m)
    return m


# ---------------------------------------------------------------------------
# models_list
# ---------------------------------------------------------------------------

def test_models_list_returns_formatted(mcp):
    with patch("kaggle_mcp.models.get_client") as mock_gc:
        m = MagicMock()
        m.title = "GPT-2"
        m.ref = "openai/gpt-2"
        mock_gc.return_value.models.model_api_client.list_models.return_value.models = [m]

        result = mcp.tools["models_list"]()
        assert "GPT-2" in result
        assert "openai/gpt-2" in result


def test_models_list_empty(mcp):
    with patch("kaggle_mcp.models.get_client") as mock_gc:
        mock_gc.return_value.models.model_api_client.list_models.return_value.models = []
        result = mcp.tools["models_list"]()
        assert result == "No models found."


# ---------------------------------------------------------------------------
# model_get
# ---------------------------------------------------------------------------

def test_model_get(mcp):
    with patch("kaggle_mcp.models.get_client") as mock_gc:
        resp = MagicMock()
        resp.to_dict.return_value = {"title": "GPT-2", "ref": "openai/gpt-2"}
        mock_gc.return_value.models.model_api_client.get_model.return_value = resp

        result = mcp.tools["model_get"]("openai", "gpt-2")
        assert "GPT-2" in result or "openai/gpt-2" in result


# ---------------------------------------------------------------------------
# model_create
# ---------------------------------------------------------------------------

def test_model_create(mcp):
    with patch("kaggle_mcp.models.get_client") as mock_gc:
        resp = MagicMock()
        resp.to_dict.return_value = {"ref": "user/my-model", "status": "ok"}
        mock_gc.return_value.models.model_api_client.create_model.return_value = resp

        result = mcp.tools["model_create"]("user", "my-model", "My Model")
        assert "my-model" in result or "ok" in result


def test_model_create_error(mcp):
    with patch("kaggle_mcp.models.get_client") as mock_gc:
        mock_gc.return_value.models.model_api_client.create_model.side_effect = Exception("conflict")
        result = mcp.tools["model_create"]("user", "dup", "Dup")
        assert "Error" in result


# ---------------------------------------------------------------------------
# model_update
# ---------------------------------------------------------------------------

def test_model_update(mcp):
    with patch("kaggle_mcp.models.get_client") as mock_gc:
        resp = MagicMock()
        resp.to_dict.return_value = {"status": "updated"}
        mock_gc.return_value.models.model_api_client.update_model.return_value = resp

        result = mcp.tools["model_update"]("user", "my-model", title="New Title")
        assert "updated" in result or "New Title" in result


# ---------------------------------------------------------------------------
# model_delete
# ---------------------------------------------------------------------------

def test_model_delete_success(mcp):
    with patch("kaggle_mcp.models.get_client") as mock_gc:
        resp = MagicMock()
        resp.error = None
        mock_gc.return_value.models.model_api_client.delete_model.return_value = resp

        result = mcp.tools["model_delete"]("user", "my-model")
        assert "deleted" in result.lower()


def test_model_delete_error_response(mcp):
    with patch("kaggle_mcp.models.get_client") as mock_gc:
        resp = MagicMock()
        resp.error = "not found"
        mock_gc.return_value.models.model_api_client.delete_model.return_value = resp

        result = mcp.tools["model_delete"]("user", "my-model")
        assert "not found" in result


# ---------------------------------------------------------------------------
# model_instances_list
# ---------------------------------------------------------------------------

def test_model_instances_list(mcp):
    with patch("kaggle_mcp.models.get_client") as mock_gc:
        inst = MagicMock()
        inst.id = 1
        inst.overview = "PyTorch weights"
        inst.framework = "pytorch"
        resp = MagicMock()
        resp.instances = [inst]
        mock_gc.return_value.models.model_api_client.list_model_instances.return_value = resp

        result = mcp.tools["model_instances_list"]("openai", "gpt-2")
        assert "pytorch" in result.lower() or "PyTorch" in result


def test_model_instances_list_empty(mcp):
    with patch("kaggle_mcp.models.get_client") as mock_gc:
        resp = MagicMock()
        resp.instances = []
        mock_gc.return_value.models.model_api_client.list_model_instances.return_value = resp

        result = mcp.tools["model_instances_list"]("openai", "gpt-2")
        assert "No instances" in result


# ---------------------------------------------------------------------------
# model_instance_get
# ---------------------------------------------------------------------------

def test_model_instance_get(mcp):
    with patch("kaggle_mcp.models.get_client") as mock_gc, \
         patch("kagglesdk.models.types.model_api_service.ApiGetModelInstanceRequest"):
        resp = MagicMock()
        resp.to_dict.return_value = {"framework": "pytorch", "slug": "default"}
        mock_gc.return_value.models.model_api_client.get_model_instance.return_value = resp

        result = mcp.tools["model_instance_get"]("openai", "gpt-2", "pytorch", "default")
        assert "pytorch" in result


# ---------------------------------------------------------------------------
# model_instance_create
# ---------------------------------------------------------------------------

def test_model_instance_create(mcp):
    with patch("kaggle_mcp.models.get_client") as mock_gc, \
         patch("kagglesdk.models.types.model_api_service.ApiCreateModelInstanceRequestBody"), \
         patch("kagglesdk.models.types.model_api_service.ApiCreateModelInstanceRequest"):
        resp = MagicMock()
        resp.to_dict.return_value = {"status": "created"}
        mock_gc.return_value.models.model_api_client.create_model_instance.return_value = resp

        result = mcp.tools["model_instance_create"]("user", "my-model", "pytorch", "default")
        assert "created" in result


# ---------------------------------------------------------------------------
# model_instance_versions
# ---------------------------------------------------------------------------

def test_model_instance_versions(mcp):
    with patch("kaggle_mcp.models.get_client") as mock_gc, \
         patch("kagglesdk.models.types.model_api_service.ApiListModelInstanceVersionsRequest"):
        resp = MagicMock()
        resp.version_list.to_dict.return_value = {"versions": [{"version_number": 1}]}
        mock_gc.return_value.models.model_api_client.list_model_instance_versions.return_value = resp

        result = mcp.tools["model_instance_versions"]("openai", "gpt-2", "pytorch", "default")
        assert "1" in result


# ---------------------------------------------------------------------------
# model_instance_version_create
# ---------------------------------------------------------------------------

def test_model_instance_version_create(mcp):
    with patch("kaggle_mcp.models.get_client") as mock_gc, \
         patch("kagglesdk.models.types.model_api_service.ApiCreateModelInstanceVersionRequest"):
        resp = MagicMock()
        resp.to_dict.return_value = {"version_number": 2}
        mock_gc.return_value.models.model_api_client.create_model_instance_version.return_value = resp

        result = mcp.tools["model_instance_version_create"](
            "user", "my-model", "pytorch", "default", "v2 notes"
        )
        assert "2" in result
