"""Unit tests for project-relative path resolution in MCP server configs."""

from pathlib import Path

from navi.mcp.config import McpServerConfig, project_root, resolve_paths


class TestProjectRoot:
    def test_is_the_directory_holding_the_config_dir(self, monkeypatch, tmp_path: Path):
        monkeypatch.chdir(tmp_path)
        assert project_root() == tmp_path


class TestResolvePaths:
    def test_relative_command_and_cwd_become_absolute(self, tmp_path: Path):
        cfg = McpServerConfig(
            command="./mcp-servers/my_server/.venv/bin/python",
            cwd="./mcp-servers/my_server",
        )
        resolved = resolve_paths(cfg, tmp_path)
        assert resolved.command == str(tmp_path / "mcp-servers/my_server/.venv/bin/python")
        assert resolved.cwd == str(tmp_path / "mcp-servers/my_server")

    def test_a_relative_path_without_the_dot_slash_still_resolves(self, tmp_path: Path):
        """`command`/`cwd` are always paths — no marker needed there."""
        cfg = McpServerConfig(command="mcp-servers/x/.venv/bin/python")
        assert resolve_paths(cfg, tmp_path).command == str(
            tmp_path / "mcp-servers/x/.venv/bin/python"
        )

    def test_absolute_paths_are_left_alone(self, tmp_path: Path):
        cfg = McpServerConfig(
            command="/usr/bin/python3",
            cwd="/srv/somewhere",
            env={"TOKEN_PATH": "/etc/navi/token"},
        )
        assert resolve_paths(cfg, tmp_path) == cfg

    def test_relative_env_and_args_resolve_on_the_marker(self, tmp_path: Path):
        cfg = McpServerConfig(
            command="./bin/python",
            args=["-m", "app.mcp_server", "--data", "./data"],
            env={"SESSION_FILES_DIR": "./session_files", "MCP_TRANSPORT": "stdio"},
        )
        resolved = resolve_paths(cfg, tmp_path)
        assert resolved.args == ["-m", "app.mcp_server", "--data", str(tmp_path / "data")]
        assert resolved.env == {
            "SESSION_FILES_DIR": str(tmp_path / "session_files"),
            "MCP_TRANSPORT": "stdio",
        }

    def test_home_relative_paths_expand(self, tmp_path: Path):
        cfg = McpServerConfig(command="~/bin/python")
        assert resolve_paths(cfg, tmp_path).command == str(Path("~/bin/python").expanduser())

    def test_env_values_that_are_not_paths_are_untouched(self, tmp_path: Path):
        """`env` carries URLs and flags too — the `./` marker is what opts in."""
        cfg = McpServerConfig(
            command="./bin/python",
            env={"BASE_URL": "http://localhost:8000/mcp", "FLAG": "a/b"},
        )
        resolved = resolve_paths(cfg, tmp_path)
        assert resolved.env == {"BASE_URL": "http://localhost:8000/mcp", "FLAG": "a/b"}

    def test_http_transport_is_untouched(self, tmp_path: Path):
        cfg = McpServerConfig(transport="sse", url="http://127.0.0.1:8098/mcp")
        assert resolve_paths(cfg, tmp_path) == cfg

    def test_does_not_mutate_the_original(self, tmp_path: Path):
        """`save_mcp_servers` writes configs back to the file: a resolved copy
        leaking into it would bake this machine's paths into a tracked file."""
        cfg = McpServerConfig(command="./mcp-servers/x/.venv/bin/python")
        resolve_paths(cfg, tmp_path)
        assert cfg.command == "./mcp-servers/x/.venv/bin/python"

    def test_default_root_is_the_project_root(self, monkeypatch, tmp_path: Path):
        monkeypatch.chdir(tmp_path)
        cfg = McpServerConfig(cwd="./mcp-servers/x")
        assert resolve_paths(cfg).cwd == str(tmp_path / "mcp-servers/x")
