"""Tests for cleanbuild module."""

from __future__ import annotations

import platform
import tempfile
from pathlib import Path

import pytest

from ..cli import SearchResult


class TestCleanBuild:
    """Test cases for clean_build_artifacts function."""

    def test_clean_empty_directory(self):
        """Test cleaning directory with no artifacts."""
        with tempfile.TemporaryDirectory() as temp_dir:
            directory = Path(temp_dir)
            result = SearchResult.from_path(directory)

            # For empty directory, no folders should be found
            assert result.delete_count == 0
            assert len(result.folders_to_delete) == 0

    def test_clean_with_build_dirs(self):
        """Test cleaning directory with build artifacts."""
        with tempfile.TemporaryDirectory() as temp_dir:
            directory = Path(temp_dir)

            # Create build directories
            build_dirs = ["build", "dist"]  # Only these are in _BUILD_FOLDERS
            for build_dir in build_dirs:
                (directory / build_dir).mkdir()
                (directory / build_dir / "dummy_file.txt").write_text("test")

            result = SearchResult.from_path(directory)

            assert result.delete_count == 2  # Only build and dist folders
            assert len(result.folders_to_delete) == 2

    def test_clean_with_pyc_files(self):
        """Test cleaning directory with Python cache files."""
        with tempfile.TemporaryDirectory() as temp_dir:
            directory = Path(temp_dir)

            # Create build directories that match _BUILD_FOLDERS
            build_dir = directory / "build"
            build_dir.mkdir()
            (build_dir / "__pycache__").mkdir()  # This won't be counted as separate
            (build_dir / "dummy.pyc").write_text("compiled")

            result = SearchResult.from_path(directory)

            assert result.delete_count == 1  # Only the build directory

    def test_clean_with_coverage_files(self):
        """Test cleaning directory with coverage files."""
        with tempfile.TemporaryDirectory() as temp_dir:
            directory = Path(temp_dir)

            # Create build directory
            build_dir = directory / "build"
            build_dir.mkdir()
            (build_dir / "temp.log").write_text("log content")
            (build_dir / "debug.txt").write_text("debug info")

            result = SearchResult.from_path(directory)

            assert result.delete_count == 1  # Only build directory is counted

    def test_clean_nonexistent_directory(self):
        """Test cleaning nonexistent directory."""
        with tempfile.TemporaryDirectory() as temp_dir:
            nonexistent_dir = Path(temp_dir) / "nonexistent"
            result = SearchResult.from_path(nonexistent_dir)

            assert result.delete_count == 0
            assert len(result.folders_to_delete) == 0

    @pytest.mark.skipif(
        platform.system() == "Windows",
        reason="Windows requires admin privileges for symlinks",
    )
    def test_clean_with_symlinks(self):
        """Test cleaning directory with symbolic links (should be skipped)."""
        with tempfile.TemporaryDirectory() as temp_dir:
            directory = Path(temp_dir)

            # Create a build directory
            build_dir = directory / "build"
            build_dir.mkdir()

            # Create a symlink inside build directory
            target_file = build_dir / "target.txt"
            target_file.write_text("target")
            symlink_file = build_dir / "link.txt"
            symlink_file.symlink_to(target_file)

            result = SearchResult.from_path(directory)

            assert result.delete_count == 1  # Build directory should be found

    def test_clean_readonly_files(self):
        """Test cleaning directory with readonly files."""
        with tempfile.TemporaryDirectory() as temp_dir:
            directory = Path(temp_dir)

            # Create readonly build directory
            build_dir = directory / "build"
            build_dir.mkdir()
            readonly_file = build_dir / "readonly.txt"
            readonly_file.write_text("readonly content")
            readonly_file.chmod(0o444)  # Read-only

            result = SearchResult.from_path(directory)

            # Directory should be found regardless of file permissions
            assert result.delete_count == 1

    def test_dry_run_mode(self):
        """Test dry run mode doesn't actually delete files."""
        with tempfile.TemporaryDirectory() as temp_dir:
            directory = Path(temp_dir)

            # Create build directory
            build_dir = directory / "build"
            build_dir.mkdir()
            (build_dir / "file.txt").write_text("test content")

            # SearchResult doesn't have dry_run parameter, but we can test the search
            result = SearchResult.from_path(directory)

            assert result.delete_count == 1
            assert (build_dir / "file.txt").exists()  # File should still exist before deletion

    def test_custom_patterns(self):
        """Test cleaning with custom file patterns."""
        with tempfile.TemporaryDirectory() as temp_dir:
            directory = Path(temp_dir)

            # Create build directory with various files
            build_dir = directory / "build"
            build_dir.mkdir()
            (build_dir / "temp.log").write_text("log content")
            (build_dir / "debug.txt").write_text("debug info")

            result = SearchResult.from_path(directory)

            # Only the build directory should be counted
            assert result.delete_count == 1

    def test_result_properties(self):
        """Test SearchResult properties and methods."""
        # Test empty result
        empty_result = SearchResult()
        assert empty_result.delete_count == 0
        assert len(empty_result.folders_to_delete) == 0
        assert "delete=Counter()" in repr(empty_result)

        # Test result with data
        test_path = Path("/test/build")
        result = SearchResult(root_dir=Path("/test"), folders_to_delete=[test_path])
        assert result.delete_count == 1
        assert len(result.folders_to_delete) == 1
        assert test_path in result.folders_to_delete
