import base64
import tempfile
import unittest
from pathlib import Path
from unittest.mock import MagicMock

from abstra_internals.controllers.main import MainController
from abstra_internals.settings import Settings

Settings.set_root_path("/tmp")

FAKE_JPEG = b"\xff\xd8\xff\xe0" + b"fake-jpeg-bytes" * 10


def _make_controller():
    """MainController mock with the real browser_screenshot bound and
    _browser_call stubbed to write a fake screenshot file, like the
    browser thread does."""
    controller = MagicMock()
    controller.browser_screenshot = MainController.browser_screenshot.__get__(
        controller
    )

    calls = []
    state = {}

    def browser_call(method, *args, **kwargs):
        calls.append((method, args, kwargs))
        f = tempfile.NamedTemporaryFile(delete=False, suffix=".jpg")
        Path(f.name).write_bytes(FAKE_JPEG)
        state["last_path"] = f.name
        return Path(f.name)

    controller._browser_call = MagicMock(side_effect=browser_call)
    return controller, calls, state


class TestBrowserScreenshot(unittest.TestCase):
    def test_returns_image_content_the_model_can_see(self):
        """The cloud-api toolCaller converts __imageContent results into a
        real image attachment; the contract is __imageContent/mimeType/dataUri."""
        controller, _, _ = _make_controller()

        result = controller.browser_screenshot("tab-1")

        self.assertIs(result["__imageContent"], True)
        self.assertEqual(result["mimeType"], "image/jpeg")
        self.assertTrue(result["dataUri"].startswith("data:image/jpeg;base64,"))
        b64 = result["dataUri"].split(",", 1)[1]
        self.assertEqual(base64.b64decode(b64), FAKE_JPEG)

    def test_passes_marker_and_highlight_options_to_browser(self):
        controller, calls, _ = _make_controller()

        controller.browser_screenshot(
            "tab-1", show_markers=True, highlight_element="#btn"
        )

        method, args, _kwargs = calls[0]
        self.assertEqual(method, "screenshot")
        self.assertEqual(args, ("tab-1", True, "#btn"))

    def test_temp_file_removed_after_encoding(self):
        controller, _, state = _make_controller()

        controller.browser_screenshot("tab-1")

        self.assertFalse(Path(state["last_path"]).exists())


if __name__ == "__main__":
    unittest.main()
