from pathlib import Path
from unittest.mock import MagicMock, patch

import pytest

from cog_mcp import server
from cog_mcp.config import Config


def test_main_bootstraps_server_and_runs_stdio(
    tmp_path: Path, monkeypatch: pytest.MonkeyPatch, sample_config: Config
) -> None:
    monkeypatch.chdir(tmp_path)
    env_path = tmp_path / ".env"
    env_path.write_text("CDF_CLUSTER=westeurope-1\n", encoding="utf-8")

    fake_client = object()
    fake_mcp = MagicMock()

    with (
        patch("cog_mcp.server.load_dotenv") as load_dotenv,
        patch("cog_mcp.server.Config.from_env", return_value=sample_config) as from_env,
        patch("cog_mcp.server.create_cognite_client", return_value=fake_client) as create_client,
        patch("cog_mcp.server.FastMCP", return_value=fake_mcp) as fastmcp_cls,
        patch("cog_mcp.server.register_resources") as register_resources,
        patch("cog_mcp.server.register_tools") as register_tools,
    ):
        server.main()

    load_dotenv.assert_called_once_with(env_path, override=False)
    from_env.assert_called_once_with()
    create_client.assert_called_once_with(sample_config)
    fastmcp_cls.assert_called_once_with("cog-mcp-experimental", instructions=server.INSTRUCTIONS)
    register_resources.assert_called_once_with(fake_mcp, fake_client, sample_config)
    register_tools.assert_called_once_with(fake_mcp, fake_client, sample_config)
    fake_mcp.run.assert_called_once_with(transport="stdio")


def test_main_exits_with_code_one_on_configuration_error(
    tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
    # No .env file created — exercises the fallback `load_dotenv(override=False)` branch
    monkeypatch.chdir(tmp_path)

    with (
        patch("cog_mcp.server.load_dotenv") as load_dotenv,
        patch("cog_mcp.server.Config.from_env", side_effect=ValueError("missing config")),
        patch("cog_mcp.server.create_cognite_client") as create_client,
        pytest.raises(SystemExit) as exc,
    ):
        server.main()

    assert exc.value.code == 1
    load_dotenv.assert_called_once_with(override=False)
    create_client.assert_not_called()
