"""Unit tests for FileService."""

import os
import tempfile

import pytest

from src.models import Workspace
from src.services.shared.file_service import FileService


@pytest.fixture
def temp_workspace():
    """Create a temporary workspace directory."""
    with tempfile.TemporaryDirectory() as tmpdir:
        ws = Workspace(
            id="00000000-0000-0000-0000-000000000001",
            name="test-ws",
            repo_id="00000000-0000-0000-0000-000000000002",
            user_id="00000000-0000-0000-0000-000000000003",
            branch="main",
            path=tmpdir,
        )
        yield ws


class TestFileService:
    """Tests for FileService."""

    def test_list_directory_empty(self, temp_workspace: Workspace):
        """Returns empty list for empty directory."""
        service = FileService()
        entries = service.list_directory(temp_workspace)
        assert entries == []

    def test_list_directory_with_files(self, temp_workspace: Workspace):
        """Returns entries sorted (dirs first, then files)."""
        # Create files and dirs
        os.makedirs(os.path.join(temp_workspace.path, "src"))
        with open(os.path.join(temp_workspace.path, "README.md"), "w") as f:
            f.write("# Test")
        with open(os.path.join(temp_workspace.path, "main.py"), "w") as f:
            f.write("print('hello')")

        service = FileService()
        entries = service.list_directory(temp_workspace)

        assert len(entries) == 3
        assert entries[0].name == "src" and entries[0].type == "directory"
        assert entries[1].name == "main.py" and entries[1].type == "file"
        assert entries[2].name == "README.md" and entries[2].type == "file"

    def test_read_file(self, temp_workspace: Workspace):
        """Reads text file content."""
        with open(os.path.join(temp_workspace.path, "test.txt"), "w") as f:
            f.write("hello world")

        service = FileService()
        content = service.read_file(temp_workspace, "test.txt")
        assert content == "hello world"

    def test_read_binary_file_rejected(self, temp_workspace: Workspace):
        """Rejects binary files."""
        with open(os.path.join(temp_workspace.path, "binary.bin"), "wb") as f:
            f.write(b"\x00\x01\x02")

        service = FileService()
        with pytest.raises(ValueError, match="Binary"):
            service.read_file(temp_workspace, "binary.bin")

    def test_write_file(self, temp_workspace: Workspace):
        """Writes file to workspace."""
        service = FileService()
        service.write_file(temp_workspace, "nested/file.txt", "content")

        assert os.path.exists(os.path.join(temp_workspace.path, "nested", "file.txt"))
        with open(os.path.join(temp_workspace.path, "nested", "file.txt")) as f:
            assert f.read() == "content"

    def test_path_escapes_workspace(self, temp_workspace: Workspace):
        """Rejects paths that escape workspace directory."""
        service = FileService()
        with pytest.raises(ValueError, match="escapes"):
            service.list_directory(temp_workspace, "../outside")
