from unittest.mock import MagicMock, patch

import pytest

from GramAddict.core.device_facade import DeviceFacade


def test_adb_retry_recovers_from_transient_error():
    # Attempt simulated disconnect on dump_hierarchy
    device_id = "test"
    app_id = "test"

    with patch("uiautomator2.connect") as mock_connect:
        mock_device = MagicMock()
        mock_connect.return_value = mock_device

        facade = DeviceFacade(device_id, app_id, None)

        # Make the first 2 calls fail, the 3rd one pass
        mock_device.dump_hierarchy.side_effect = [
            Exception("ConnectError uiautomator2"),
            Exception("RPC Error"),
            "<hierarchy></hierarchy>",
        ]

        # Patch sleep to speed up test
        with patch("GramAddict.core.device_facade.sleep"):
            res = facade.dump_hierarchy()
            assert res == "<hierarchy></hierarchy>"
            assert mock_device.dump_hierarchy.call_count == 3


def test_adb_retry_crashes_gracefully_after_all_retries():
    # Attempt simulated disconnect on dump_hierarchy
    device_id = "test"
    app_id = "test"

    with patch("uiautomator2.connect") as mock_connect:
        mock_device = MagicMock()
        mock_connect.return_value = mock_device

        facade = DeviceFacade(device_id, app_id, None)

        # Always fail
        mock_device.dump_hierarchy.side_effect = Exception("Permanent ConnectError")

        with patch("GramAddict.core.device_facade.sleep"):
            with pytest.raises(Exception, match="Permanent ConnectError"):
                facade.dump_hierarchy()
            assert mock_device.dump_hierarchy.call_count == 3
