"""
Tests for subprocess.run usage in open folder functions.

These tests verify that subprocess.run is used with start_new_session=True
on Linux and macOS to prevent zombie processes and file descriptor leaks.

The tests use source code inspection to verify the implementation details,
which is more reliable than integration tests for verifying specific
subprocess parameters.
"""

import inspect
import re


class TestSubprocessRunNotPopen:
    """Tests to verify Popen is NOT used (would cause zombie processes)."""

    def test_settings_routes_open_file_location_uses_subprocess_run_not_popen(
        self,
    ):
        """Verify settings_routes.open_file_location uses subprocess.run, not Popen."""
        from local_deep_research.web.routes import settings_routes

        func_source = inspect.getsource(settings_routes.open_file_location)

        # subprocess.run should be used
        assert "subprocess.run" in func_source, (
            "open_file_location should use subprocess.run"
        )

        # Popen should NOT be called in this function
        # Note: "Popen" may appear in comments explaining why we don't use it,
        # so we check for actual Popen calls (Popen( or subprocess.Popen)
        assert (
            "Popen(" not in func_source
            and "subprocess.Popen" not in func_source
        ), "open_file_location should NOT call Popen (causes zombie processes)"

    def test_research_routes_open_file_location_uses_subprocess_run_not_popen(
        self,
    ):
        """Verify research_routes.open_file_location uses subprocess.run, not Popen."""
        from local_deep_research.web.routes import research_routes

        func_source = inspect.getsource(research_routes.open_file_location)

        # subprocess.run should be used
        assert "subprocess.run" in func_source, (
            "open_file_location should use subprocess.run"
        )

        # Popen should NOT be used in this function
        assert "Popen" not in func_source, (
            "open_file_location should NOT use Popen (causes zombie processes)"
        )


class TestStartNewSessionOnUnix:
    """Tests to verify start_new_session=True is used on Unix systems."""

    def test_settings_routes_uses_start_new_session_for_xdg_open(self):
        """Verify settings_routes uses start_new_session=True with xdg-open (Linux)."""
        from local_deep_research.web.routes import settings_routes

        func_source = inspect.getsource(settings_routes.open_file_location)

        # Check for xdg-open usage
        assert "xdg-open" in func_source, (
            "open_file_location should use xdg-open on Linux"
        )

        # Check for start_new_session parameter
        assert "start_new_session=True" in func_source, (
            "open_file_location should use start_new_session=True"
        )

        # Verify the subprocess.run call with xdg-open has start_new_session
        # Look for the pattern: subprocess.run(["xdg-open", ...], start_new_session=True
        linux_block_match = re.search(
            r'else:.*?#.*?Linux.*?subprocess\.run\(\s*\["xdg-open".*?start_new_session\s*=\s*True',
            func_source,
            re.DOTALL,
        )
        assert linux_block_match is not None, (
            "Linux xdg-open call should include start_new_session=True"
        )

    def test_settings_routes_uses_start_new_session_for_macos_open(self):
        """Verify settings_routes uses start_new_session=True with open (macOS)."""
        from local_deep_research.web.routes import settings_routes

        func_source = inspect.getsource(settings_routes.open_file_location)

        # Check for Darwin/macOS handling
        assert "Darwin" in func_source, (
            "open_file_location should handle Darwin/macOS"
        )

        # Check that macOS uses the 'open' command with start_new_session
        macos_block_match = re.search(
            r'Darwin.*?subprocess\.run\(\s*\["open".*?start_new_session\s*=\s*True',
            func_source,
            re.DOTALL,
        )
        assert macos_block_match is not None, (
            "macOS open call should include start_new_session=True"
        )

    def test_research_routes_uses_start_new_session_for_xdg_open(self):
        """Verify research_routes uses start_new_session=True with xdg-open (Linux)."""
        from local_deep_research.web.routes import research_routes

        func_source = inspect.getsource(research_routes.open_file_location)

        # Check for xdg-open usage
        assert "xdg-open" in func_source, (
            "open_file_location should use xdg-open on Linux"
        )

        # Check for start_new_session parameter
        assert "start_new_session=True" in func_source, (
            "open_file_location should use start_new_session=True"
        )

        # Verify the subprocess.run call with xdg-open has start_new_session
        linux_block_match = re.search(
            r'else:.*?#.*?Linux.*?subprocess\.run\(\s*\["xdg-open".*?start_new_session\s*=\s*True',
            func_source,
            re.DOTALL,
        )
        assert linux_block_match is not None, (
            "Linux xdg-open call should include start_new_session=True"
        )

    def test_research_routes_uses_start_new_session_for_macos_open(self):
        """Verify research_routes uses start_new_session=True with open (macOS)."""
        from local_deep_research.web.routes import research_routes

        func_source = inspect.getsource(research_routes.open_file_location)

        # Check for Darwin/macOS handling
        assert "Darwin" in func_source, (
            "open_file_location should handle Darwin/macOS"
        )

        # Check that macOS uses the 'open' command with start_new_session
        macos_block_match = re.search(
            r'Darwin.*?subprocess\.run\(\s*\["open".*?start_new_session\s*=\s*True',
            func_source,
            re.DOTALL,
        )
        assert macos_block_match is not None, (
            "macOS open call should include start_new_session=True"
        )


class TestWindowsDoesNotUseStartNewSession:
    """Tests to verify Windows does not need start_new_session (uses explorer)."""

    def test_settings_routes_windows_uses_explorer(self):
        """Verify settings_routes uses explorer on Windows (no start_new_session needed)."""
        from local_deep_research.web.routes import settings_routes

        func_source = inspect.getsource(settings_routes.open_file_location)

        # Windows should use explorer
        assert '"Windows"' in func_source or "'Windows'" in func_source, (
            "open_file_location should check for Windows platform"
        )

        # Windows block should use explorer
        windows_match = re.search(
            r'Windows.*?subprocess\.run\(\s*\["explorer"',
            func_source,
            re.DOTALL,
        )
        assert windows_match is not None, "Windows should use explorer command"

    def test_research_routes_windows_uses_explorer(self):
        """Verify research_routes uses explorer on Windows."""
        from local_deep_research.web.routes import research_routes

        func_source = inspect.getsource(research_routes.open_file_location)

        # Windows should use explorer
        assert '"Windows"' in func_source or "'Windows'" in func_source, (
            "open_file_location should check for Windows platform"
        )

        # Windows block should use explorer
        windows_match = re.search(
            r'Windows.*?subprocess\.run\(\s*\["explorer"',
            func_source,
            re.DOTALL,
        )
        assert windows_match is not None, "Windows should use explorer command"


class TestSubprocessCommentDocumentation:
    """Tests to verify the code has proper comments about zombie process prevention."""

    def test_settings_routes_has_zombie_prevention_comment(self):
        """Verify settings_routes documents why start_new_session is used."""
        from local_deep_research.web.routes import settings_routes

        func_source = inspect.getsource(settings_routes.open_file_location)

        # Should have comment explaining the fix
        assert "start_new_session" in func_source and (
            "zombie" in func_source.lower()
            or "detach" in func_source.lower()
            or "file descriptor" in func_source.lower()
        ), "Code should document why start_new_session is used"

    def test_research_routes_has_detach_comment(self):
        """Verify research_routes documents subprocess detachment."""
        from local_deep_research.web.routes import research_routes

        func_source = inspect.getsource(research_routes.open_file_location)

        # Should have comment explaining the fix
        assert "start_new_session" in func_source and (
            "detach" in func_source.lower()
            or "fully detach" in func_source.lower()
        ), (
            "Code should document why start_new_session is used (detach subprocess)"
        )


class TestPlatformHandling:
    """Tests for proper platform detection and handling."""

    def test_settings_routes_handles_all_platforms(self):
        """Verify settings_routes handles Windows, macOS, and Linux."""
        from local_deep_research.web.routes import settings_routes

        func_source = inspect.getsource(settings_routes.open_file_location)

        # Should handle all three platforms
        assert "Windows" in func_source, "Should handle Windows"
        assert "Darwin" in func_source, "Should handle macOS (Darwin)"
        # Linux is the else case, verified by xdg-open
        assert "xdg-open" in func_source, "Should handle Linux with xdg-open"

    def test_research_routes_handles_all_platforms(self):
        """Verify research_routes handles Windows, macOS, and Linux."""
        from local_deep_research.web.routes import research_routes

        func_source = inspect.getsource(research_routes.open_file_location)

        # Should handle all three platforms
        assert "Windows" in func_source, "Should handle Windows"
        assert "Darwin" in func_source, "Should handle macOS (Darwin)"
        # Linux is the else case, verified by xdg-open
        assert "xdg-open" in func_source, "Should handle Linux with xdg-open"

    def test_settings_routes_uses_platform_system(self):
        """Verify settings_routes uses platform.system() for OS detection."""
        from local_deep_research.web.routes import settings_routes

        func_source = inspect.getsource(settings_routes.open_file_location)

        assert "platform.system()" in func_source, (
            "Should use platform.system() for OS detection"
        )

    def test_research_routes_uses_platform_system(self):
        """Verify research_routes uses platform.system() for OS detection."""
        from local_deep_research.web.routes import research_routes

        func_source = inspect.getsource(research_routes.open_file_location)

        assert "platform.system()" in func_source, (
            "Should use platform.system() for OS detection"
        )
