from __future__ import annotations

import asyncio
from datetime import datetime
from io import StringIO
from unittest.mock import MagicMock, patch

from arcade_cli.server import _display_deployment_logs, _stream_deployment_logs
from rich.console import Console


def test_display_deployment_logs_preserves_square_bracket_content() -> None:
    buf = StringIO()
    test_console = Console(file=buf, force_terminal=False)

    mock_response = MagicMock()
    mock_response.raise_for_status.return_value = None
    mock_response.json.return_value = [
        {"timestamp": "2026-01-15T15:30:00Z", "line": "[INFO] startup [ERROR] details"}
    ]
    mock_client = MagicMock()
    mock_client.get.return_value = mock_response

    import arcade_cli.server as server_mod

    original_console = server_mod.console
    server_mod.console = test_console
    try:
        with (
            patch("arcade_cli.server.httpx.Client") as mock_httpx_client,
            patch("arcade_cli.server._format_timestamp_to_local", return_value="2026-01-15 10:30:00 EST"),
        ):
            mock_httpx_client.return_value.__enter__.return_value = mock_client
            _display_deployment_logs(
                "http://localhost:8123/logs",
                {},
                datetime(2026, 1, 15, 15, 30, 0),
                datetime(2026, 1, 15, 15, 35, 0),
                debug=False,
            )
    finally:
        server_mod.console = original_console

    output = buf.getvalue()
    assert "[2026-01-15 10:30:00 EST]" in output
    assert "[INFO]" in output
    assert "[ERROR]" in output


def test_stream_deployment_logs_preserves_square_bracket_content() -> None:
    buf = StringIO()
    test_console = Console(file=buf, force_terminal=False)

    class FakeStreamResponse:
        async def __aenter__(self) -> FakeStreamResponse:
            return self

        async def __aexit__(self, exc_type, exc, tb) -> None:  # type: ignore[no-untyped-def]
            return None

        def raise_for_status(self) -> None:
            return None

        async def aiter_lines(self):  # type: ignore[no-untyped-def]
            yield 'data: {"Timestamp":"2026-01-15T15:30:00Z","Line":"[ERROR] stream details"}'
            yield "[INFO] plain stream line"

    class FakeAsyncClient:
        async def __aenter__(self) -> FakeAsyncClient:
            return self

        async def __aexit__(self, exc_type, exc, tb) -> None:  # type: ignore[no-untyped-def]
            return None

        def stream(self, *args, **kwargs) -> FakeStreamResponse:  # type: ignore[no-untyped-def]
            return FakeStreamResponse()

    import arcade_cli.server as server_mod

    original_console = server_mod.console
    server_mod.console = test_console
    try:
        with (
            patch("arcade_cli.server.httpx.AsyncClient", return_value=FakeAsyncClient()),
            patch("arcade_cli.server._format_timestamp_to_local", return_value="2026-01-15 10:30:00 EST"),
        ):
            asyncio.run(
                _stream_deployment_logs(
                    "http://localhost:8123/logs/stream",
                    {},
                    datetime(2026, 1, 15, 15, 30, 0),
                    datetime(2026, 1, 15, 15, 35, 0),
                    debug=False,
                )
            )
    finally:
        server_mod.console = original_console

    output = buf.getvalue()
    assert "[2026-01-15 10:30:00 EST]" in output
    assert "[ERROR]" in output
    assert "[INFO] plain stream line" in output
