import pytest
import sys
import os
import threading
import time

sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))


def test_render_warmup_indicator_function_exists() -> None:
 """render_warmup_status_indicator is importable from src.gui_2."""
 from src.gui_2 import render_warmup_status_indicator
 assert callable(render_warmup_status_indicator)


def test_callback_function_exists() -> None:
 """_on_warmup_complete_callback is importable from src.gui_2."""
 from src.gui_2 import _on_warmup_complete_callback
 assert callable(_on_warmup_complete_callback)


def test_callback_sets_timestamp() -> None:
 """_on_warmup_complete_callback sets _warmup_completion_ts and appends to toast list."""
 from src.gui_2 import _on_warmup_complete_callback
 class MockApp: pass
 app = MockApp()
 status = {"pending": [], "completed": ["a", "b", "c"], "failed": []}
 _on_warmup_complete_callback(app, status)
 assert hasattr(app, "_warmup_completion_ts")
 assert isinstance(app._warmup_completion_ts, float)
 assert app._warmup_completion_ts > 0
 assert hasattr(app, "_warmup_toast_lock")
 assert isinstance(app._warmup_toast_lock, type(threading.Lock()))
 assert hasattr(app, "_warmup_toast_messages")
 assert len(app._warmup_toast_messages) == 1
 ts, msg = app._warmup_toast_messages[0]
 assert msg == "All imports ready (3 modules)"


def test_callback_with_failures_uses_warning_message() -> None:
 """_on_warmup_complete_callback uses a failures message when failed is non-empty."""
 from src.gui_2 import _on_warmup_complete_callback
 class MockApp: pass
 app = MockApp()
 status = {"pending": [], "completed": ["a"], "failed": ["b", "c"]}
 _on_warmup_complete_callback(app, status)
 ts, msg = app._warmup_toast_messages[0]
 assert "2 failures" in msg
 assert "3 modules" in msg


def test_callback_is_thread_safe_under_concurrent_invocation() -> None:
 """10 concurrent callback invocations all append to the toast list."""
 from src.gui_2 import _on_warmup_complete_callback
 class MockApp: pass
 app = MockApp()
 def fire():
  for _ in range(10):
   _on_warmup_complete_callback(app, {"pending": [], "completed": ["x"], "failed": []})
 threads = [threading.Thread(target=fire) for _ in range(10)]
 for t in threads: t.start()
 for t in threads: t.join()
 assert len(app._warmup_toast_messages) == 100


def test_live_render_warmup_indicator_does_not_crash(live_gui) -> None:
 """Live: render_warmup_status_indicator() can be called in the running GUI without crashing.

 Verifies the function is callable in a real ImGui frame context and that the
 controller exposes the warmup_status API the indicator consumes.
 """
 from src.gui_2 import render_warmup_status_indicator
 from src.api_hook_client import ApiHookClient
 client = ApiHookClient()
 assert client.wait_for_server(timeout=10)
 # The live_gui fixture has the GUI running. The function should be
 # importable and the controller should expose warmup_status.
 diag = client.get_warmup_status()
 assert "pending" in diag
 assert "completed" in diag
 assert "failed" in diag
 # The function is callable; it would render on the next frame.
 assert callable(render_warmup_status_indicator)
