"""Unit tests for navari_cli.file_utils module."""

from unittest.mock import patch

from navari_cli.file_utils import find_workspace_file, open_url_in_browser, open_with_system_app, unique_path

# ============================================================================
# find_workspace_file
# ============================================================================


class TestFindWorkspaceFile:
    FILES = [
        {"name": "file.txt", "path": "/workspace/folder1/file.txt", "url": "https://s/f1"},
        {"name": "file.txt", "path": "/workspace/folder2/file.txt", "url": "https://s/f2"},
        {"name": "index.html", "path": "/workspace/app/index.html", "url": "https://s/idx"},
    ]

    def test_basename_unique(self):
        assert find_workspace_file(self.FILES, "index.html") == "https://s/idx"

    def test_basename_ambiguous_returns_first(self):
        """When multiple files share a basename, first match wins."""
        assert find_workspace_file(self.FILES, "file.txt") == "https://s/f1"

    def test_path_match_folder1(self):
        assert find_workspace_file(self.FILES, "folder1/file.txt") == "https://s/f1"

    def test_path_match_folder2(self):
        assert find_workspace_file(self.FILES, "folder2/file.txt") == "https://s/f2"

    def test_absolute_display_path(self):
        assert find_workspace_file(self.FILES, "/workspace/folder2/file.txt") == "https://s/f2"

    def test_not_found(self):
        assert find_workspace_file(self.FILES, "missing.txt") is None

    def test_empty_list(self):
        assert find_workspace_file([], "file.txt") is None

    def test_path_takes_priority_over_basename(self):
        """Path match (folder2) wins over basename match (folder1 = first)."""
        assert find_workspace_file(self.FILES, "folder2/file.txt") == "https://s/f2"


# ============================================================================
# unique_path
# ============================================================================


class TestUniquePath:
    def test_no_conflict(self, tmp_path):
        p = tmp_path / "file.txt"
        assert unique_path(p) == p

    def test_one_conflict(self, tmp_path):
        (tmp_path / "file.txt").write_text("existing")
        result = unique_path(tmp_path / "file.txt")
        assert result == tmp_path / "file (1).txt"

    def test_multiple_conflicts(self, tmp_path):
        (tmp_path / "file.txt").write_text("a")
        (tmp_path / "file (1).txt").write_text("b")
        (tmp_path / "file (2).txt").write_text("c")
        result = unique_path(tmp_path / "file.txt")
        assert result == tmp_path / "file (3).txt"

    def test_preserves_extension(self, tmp_path):
        (tmp_path / "report.pdf").write_text("existing")
        result = unique_path(tmp_path / "report.pdf")
        assert result.suffix == ".pdf"
        assert result.stem == "report (1)"

    def test_no_extension(self, tmp_path):
        (tmp_path / "Makefile").write_text("existing")
        result = unique_path(tmp_path / "Makefile")
        assert result == tmp_path / "Makefile (1)"


# ============================================================================
# open_url_in_browser
# ============================================================================


class TestOpenUrlInBrowser:
    def test_appends_jwt(self):
        with patch("navari_cli.file_utils.webbrowser.open") as mock:
            open_url_in_browser("https://server/file.txt", "mytoken")
        mock.assert_called_once_with("https://server/file.txt?jwt=mytoken")

    def test_appends_jwt_with_existing_query(self):
        with patch("navari_cli.file_utils.webbrowser.open") as mock:
            open_url_in_browser("https://server/file.txt?v=1", "mytoken")
        mock.assert_called_once_with("https://server/file.txt?v=1&jwt=mytoken")


# ============================================================================
# open_with_system_app
# ============================================================================


class TestOpenWithSystemApp:
    def test_windows(self, tmp_path):
        f = tmp_path / "test.txt"
        f.write_text("hi")
        with (
            patch("navari_cli.file_utils.platform.system", return_value="Windows"),
            patch("navari_cli.file_utils.os.startfile", create=True) as mock_sf,
        ):
            open_with_system_app(f)
        mock_sf.assert_called_once_with(f)

    def test_macos(self, tmp_path):
        f = tmp_path / "test.txt"
        f.write_text("hi")
        with (
            patch("navari_cli.file_utils.platform.system", return_value="Darwin"),
            patch("navari_cli.file_utils.sp.run") as mock_run,
        ):
            open_with_system_app(f)
        mock_run.assert_called_once_with(["open", str(f)], check=False)

    def test_linux(self, tmp_path):
        f = tmp_path / "test.txt"
        f.write_text("hi")
        with (
            patch("navari_cli.file_utils.platform.system", return_value="Linux"),
            patch("navari_cli.file_utils.sp.run") as mock_run,
        ):
            open_with_system_app(f)
        mock_run.assert_called_once_with(["xdg-open", str(f)], check=False)
