"""
Test suite for cross-platform compatibility validation.

Related to Issue #145: Phase 4 - Production Readiness and Release (Week 6)
Tests Windows, macOS, and Linux compatibility including filesystem features,
symlinks, path handling, and platform-specific integrations.
"""

import pytest
import platform
import tempfile
import shutil
import os
from pathlib import Path
from unittest.mock import Mock, patch, MagicMock
from markitect.production.cross_platform_validator import (
    CrossPlatformValidator,
    PlatformFeature,
    CompatibilityResult,
    WindowsCompatibilityChecker,
    MacOSCompatibilityChecker,
    LinuxCompatibilityChecker
)


class TestCrossPlatformValidator:
    """Test cross-platform compatibility validation capabilities."""

    @pytest.fixture
    def temp_workspace(self):
        """Create temporary workspace for testing."""
        temp_dir = tempfile.mkdtemp()
        yield Path(temp_dir)
        shutil.rmtree(temp_dir, ignore_errors=True)

    @pytest.fixture
    def validator(self, temp_workspace):
        """Create CrossPlatformValidator instance."""
        return CrossPlatformValidator(
            workspace_path=temp_workspace,
            target_platforms=["windows", "macos", "linux"]
        )

    def test_windows_ntfs_filesystem_compatibility(self, validator):
        """Test NTFS filesystem compatibility testing."""
        with patch('platform.system', return_value='Windows'):
            with patch('markitect.production.cross_platform_validator.get_filesystem_type') as mock_fs:
                mock_fs.return_value = 'NTFS'

                result = validator.check_filesystem_compatibility()

                assert result.platform == "windows"
                assert result.filesystem_type == "NTFS"
                assert result.supported_features is not None
                assert PlatformFeature.SYMLINKS in result.supported_features
                assert PlatformFeature.HARDLINKS in result.supported_features

    def test_windows_symlink_alternatives(self, validator, temp_workspace):
        """Test Windows symlink alternatives (junction points, hardlinks)."""
        windows_checker = WindowsCompatibilityChecker(temp_workspace)

        # Test junction point creation
        target_dir = temp_workspace / "target_directory"
        target_dir.mkdir()
        junction_dir = temp_workspace / "junction_link"

        result = windows_checker.create_directory_link(
            target=target_dir,
            link=junction_dir,
            link_type="junction"
        )

        assert result.success is True
        assert result.link_type == "junction"
        assert result.requires_admin is False

        # Test hardlink creation
        target_file = temp_workspace / "target_file.txt"
        target_file.write_text("test content")
        hardlink_file = temp_workspace / "hardlink.txt"

        result = windows_checker.create_file_link(
            target=target_file,
            link=hardlink_file,
            link_type="hardlink"
        )

        assert result.success is True
        assert result.link_type == "hardlink"
        assert hardlink_file.read_text() == "test content"

    def test_windows_path_length_limitation_handling(self, validator):
        """Test handling of Windows 260 character path limit."""
        windows_checker = WindowsCompatibilityChecker()

        # Test path that exceeds traditional limit
        long_path = "C:\\" + "\\".join(["very_long_directory_name"] * 15) + "\\file.txt"

        result = windows_checker.validate_path_length(long_path)

        assert result.path_length > 260
        assert result.exceeds_traditional_limit is True
        assert result.long_path_support_available is not None
        assert result.suggested_alternatives is not None

    def test_windows_permission_model_compatibility(self, validator):
        """Test Windows permission model compatibility."""
        windows_checker = WindowsCompatibilityChecker()

        test_permissions = {
            "owner": "rwx",
            "group": "r-x",
            "other": "r--"
        }

        result = windows_checker.map_unix_permissions_to_windows(test_permissions)

        assert result.success is True
        assert result.windows_acl is not None
        assert result.permission_mapping is not None
        assert "Full Control" in str(result.windows_acl)

    def test_powershell_integration_testing(self, validator):
        """Test PowerShell integration testing."""
        windows_checker = WindowsCompatibilityChecker()

        # Test PowerShell command execution
        with patch('subprocess.run') as mock_run:
            mock_run.return_value.returncode = 0
            mock_run.return_value.stdout = "PowerShell 5.1.19041.1682"

            result = windows_checker.test_powershell_integration()

            assert result.success is True
            assert result.powershell_version is not None
            assert result.execution_policy_compatible is not None

    def test_macos_hfs_apfs_filesystem_compatibility(self, validator):
        """Test HFS+/APFS filesystem compatibility."""
        macos_checker = MacOSCompatibilityChecker()

        with patch('markitect.production.cross_platform_validator.get_filesystem_type') as mock_fs:
            # Test APFS
            mock_fs.return_value = 'APFS'
            result = macos_checker.check_filesystem_features()

            assert result.filesystem_type == "APFS"
            assert result.supports_snapshots is True
            assert result.supports_clones is True
            assert result.case_sensitive is not None

            # Test HFS+
            mock_fs.return_value = 'HFS+'
            result = macos_checker.check_filesystem_features()

            assert result.filesystem_type == "HFS+"
            assert result.supports_resource_forks is True

    def test_macos_symlink_behavior_validation(self, validator, temp_workspace):
        """Test macOS symlink behavior validation."""
        macos_checker = MacOSCompatibilityChecker(temp_workspace)

        # Create target file
        target_file = temp_workspace / "target.txt"
        target_file.write_text("test content")

        # Test symlink creation and behavior
        symlink_file = temp_workspace / "symlink.txt"

        result = macos_checker.create_and_validate_symlink(
            target=target_file,
            link=symlink_file
        )

        assert result.success is True
        assert result.symlink_created is True
        assert result.target_accessible is True
        assert result.permissions_preserved is not None

    def test_macos_extended_attribute_handling(self, validator, temp_workspace):
        """Test extended attribute handling on macOS."""
        macos_checker = MacOSCompatibilityChecker(temp_workspace)

        test_file = temp_workspace / "test_file.txt"
        test_file.write_text("test content")

        # Test setting and getting extended attributes
        result = macos_checker.test_extended_attributes(
            file_path=test_file,
            attributes={
                "com.markitect.asset_id": "asset_123",
                "com.markitect.content_type": "text/plain"
            }
        )

        assert result.success is True
        assert result.attributes_set is True
        assert result.attributes_retrievable is True

    def test_macos_security_features_compatibility(self, validator):
        """Test macOS security features compatibility (Gatekeeper, SIP)."""
        macos_checker = MacOSCompatibilityChecker()

        result = macos_checker.check_security_compatibility()

        assert result.gatekeeper_status is not None
        assert result.sip_status is not None
        assert result.code_signing_requirements is not None
        assert result.sandbox_compatibility is not None

    def test_homebrew_installation_compatibility(self, validator):
        """Test Homebrew installation compatibility."""
        macos_checker = MacOSCompatibilityChecker()

        with patch('shutil.which') as mock_which:
            mock_which.return_value = "/opt/homebrew/bin/brew"

            result = macos_checker.check_homebrew_compatibility()

            assert result.homebrew_available is True
            assert result.homebrew_path is not None
            assert result.installation_method is not None

    def test_linux_multiple_filesystem_support(self, validator):
        """Test multiple filesystem support (ext4, btrfs, xfs)."""
        linux_checker = LinuxCompatibilityChecker()

        filesystems = ["ext4", "btrfs", "xfs", "zfs"]

        for fs_type in filesystems:
            with patch('markitect.production.cross_platform_validator.get_filesystem_type') as mock_fs:
                mock_fs.return_value = fs_type

                result = linux_checker.check_filesystem_support(fs_type)

                assert result.filesystem_type == fs_type
                assert hasattr(result, 'supports_snapshots')
                assert hasattr(result, 'supports_clones')

    def test_linux_distribution_specific_testing(self, validator):
        """Test distribution-specific testing (Ubuntu, CentOS, Alpine)."""
        linux_checker = LinuxCompatibilityChecker()

        distributions = [
            {"name": "Ubuntu", "version": "20.04", "package_manager": "apt"},
            {"name": "CentOS", "version": "8", "package_manager": "yum"},
            {"name": "Alpine", "version": "3.14", "package_manager": "apk"}
        ]

        for distro in distributions:
            with patch('platform.freedesktop_os_release') as mock_os_release:
                mock_os_release.return_value = {
                    'NAME': distro["name"],
                    'VERSION': distro["version"]
                }

                result = linux_checker.check_distribution_compatibility(distro)

                assert result.distribution_name == distro["name"]
                assert result.version_supported is not None
                assert result.package_manager == distro["package_manager"]

    def test_container_environment_compatibility(self, validator):
        """Test container environment compatibility (Docker, Podman)."""
        linux_checker = LinuxCompatibilityChecker()

        container_runtimes = ["docker", "podman"]

        for runtime in container_runtimes:
            with patch('shutil.which') as mock_which:
                mock_which.return_value = f"/usr/bin/{runtime}"

                result = linux_checker.check_container_compatibility(runtime)

                assert result.runtime_available is True
                assert result.runtime_name == runtime
                assert result.features_supported is not None

    def test_package_manager_integration_testing(self, validator):
        """Test package manager integration testing."""
        linux_checker = LinuxCompatibilityChecker()

        package_managers = [
            {"name": "apt", "install_cmd": "apt install", "search_cmd": "apt search"},
            {"name": "yum", "install_cmd": "yum install", "search_cmd": "yum search"},
            {"name": "pacman", "install_cmd": "pacman -S", "search_cmd": "pacman -Ss"}
        ]

        for pm in package_managers:
            with patch('shutil.which') as mock_which:
                mock_which.return_value = f"/usr/bin/{pm['name']}"

                result = linux_checker.test_package_manager_integration(pm["name"])

                assert result.package_manager == pm["name"]
                assert result.available is True
                assert result.install_command is not None

    def test_systemd_service_integration(self, validator):
        """Test systemd service integration."""
        linux_checker = LinuxCompatibilityChecker()

        with patch('pathlib.Path.exists') as mock_exists:
            mock_exists.return_value = True

            result = linux_checker.check_systemd_integration()

            assert result.systemd_available is True
            assert result.service_creation_supported is not None
            assert result.user_services_supported is not None

    def test_comprehensive_platform_detection(self, validator):
        """Test comprehensive platform detection and feature mapping."""
        # Test current platform detection
        result = validator.detect_current_platform()

        assert result.platform_name is not None
        assert result.platform_version is not None
        assert result.architecture is not None
        assert result.supported_features is not None

        # Verify platform-specific features are correctly identified
        current_platform = platform.system().lower()
        expected_features = validator.get_expected_features_for_platform(current_platform)

        assert set(result.supported_features).issuperset(set(expected_features))

    def test_cross_platform_path_handling(self, validator, temp_workspace):
        """Test cross-platform path handling and normalization."""
        test_paths = [
            "/unix/style/path/file.txt",
            "C:\\Windows\\Style\\Path\\file.txt",
            "relative/path/file.txt",
            "../parent/directory/file.txt",
            "~/home/directory/file.txt"
        ]

        for test_path in test_paths:
            result = validator.normalize_path_for_platform(
                path=test_path,
                target_platform="current"
            )

            assert result.normalized_path is not None
            assert result.is_valid is not None
            assert result.platform_specific_issues is not None

    def test_symlink_compatibility_matrix(self, validator, temp_workspace):
        """Test symlink compatibility across all platforms."""
        target_file = temp_workspace / "target.txt"
        target_file.write_text("test content")

        platforms = ["windows", "macos", "linux"]
        link_types = ["symlink", "hardlink", "junction"]

        compatibility_matrix = validator.test_symlink_compatibility_matrix(
            target_file=target_file,
            platforms=platforms,
            link_types=link_types
        )

        assert len(compatibility_matrix) == len(platforms)

        for platform_result in compatibility_matrix:
            assert platform_result.platform in platforms
            assert platform_result.supported_link_types is not None
            assert platform_result.limitations is not None

    def test_unicode_filename_support(self, validator, temp_workspace):
        """Test Unicode filename support across platforms."""
        unicode_filenames = [
            "测试文件.txt",  # Chinese
            "αρχείο_δοκιμής.txt",  # Greek
            "файл_теста.txt",  # Cyrillic
            "📄_emoji_file.txt",  # Emoji
            "café_résumé.txt"  # Accented characters
        ]

        for filename in unicode_filenames:
            result = validator.test_unicode_filename_support(
                filename=filename,
                test_directory=temp_workspace
            )

            assert result.filename == filename
            assert result.creation_supported is not None
            assert result.read_supported is not None
            assert result.platform_issues is not None

    def test_file_permission_model_mapping(self, validator):
        """Test file permission model mapping between platforms."""
        unix_permissions = "755"  # rwxr-xr-x

        # Test mapping to Windows ACL
        windows_result = validator.map_permissions_to_platform(
            permissions=unix_permissions,
            source_platform="unix",
            target_platform="windows"
        )

        assert windows_result.success is True
        assert windows_result.target_permissions is not None

        # Test mapping to macOS
        macos_result = validator.map_permissions_to_platform(
            permissions=unix_permissions,
            source_platform="unix",
            target_platform="macos"
        )

        assert macos_result.success is True
        assert macos_result.target_permissions is not None

    def test_platform_specific_error_handling(self, validator):
        """Test platform-specific error handling and recovery."""
        error_scenarios = [
            {
                "platform": "windows",
                "error": "Access is denied",
                "expected_recovery": "elevate_privileges"
            },
            {
                "platform": "macos",
                "error": "Operation not permitted",
                "expected_recovery": "grant_permissions"
            },
            {
                "platform": "linux",
                "error": "Permission denied",
                "expected_recovery": "check_selinux"
            }
        ]

        for scenario in error_scenarios:
            result = validator.handle_platform_specific_error(
                platform=scenario["platform"],
                error_message=scenario["error"]
            )

            assert result.platform == scenario["platform"]
            assert result.error_recognized is True
            assert result.recovery_strategy is not None