# tests/test_hazard_description.py
import numpy as np
import pytest
from unittest.mock import MagicMock, patch


def test_import():
    from badas.analysis.hazard_description import HazardDescriptor
    assert HazardDescriptor is not None


def test_not_loaded_on_init():
    from badas.analysis.hazard_description import HazardDescriptor
    hd = HazardDescriptor()
    assert not hd.is_loaded


def test_draw_bbox_on_frame():
    """_prepare_image draws a red bbox on a copy without modifying original."""
    from badas.analysis.hazard_description import HazardDescriptor
    hd = HazardDescriptor()
    frame = np.zeros((256, 256, 3), dtype=np.uint8)
    bbox = (32, 32, 128, 128)
    result = hd._prepare_image(frame, bbox)
    # Original unchanged
    assert frame[32, 32, 2] == 0
    # Result has red bbox drawn
    assert result.shape == frame.shape
    assert result is not frame


def test_describe_returns_string_with_mock():
    """describe() calls the VLM and returns a non-empty string."""
    from badas.analysis.hazard_description import HazardDescriptor
    hd = HazardDescriptor()
    # Inject mocks to satisfy is_loaded (checks both _llm and _sampling_params)
    hd._llm = MagicMock()
    hd._processor = MagicMock()
    hd._sampling_params = MagicMock()

    frame = np.zeros((256, 256, 3), dtype=np.uint8)
    with patch.object(hd, '_run_vlm', return_value="Watch out for a pedestrian."):
        result = hd.describe(frame, bbox=(32, 32, 128, 128), risk=0.82)

    assert isinstance(result, str)
    assert len(result) > 0


def test_describe_returns_none_when_no_bbox():
    """describe() returns None when bbox is None (flat attribution map)."""
    from badas.analysis.hazard_description import HazardDescriptor
    hd = HazardDescriptor()
    frame = np.zeros((256, 256, 3), dtype=np.uint8)
    result = hd.describe(frame, bbox=None, risk=0.82)
    assert result is None
