"""ReferenceEntityService 테스트 (W5 F24 Phase 2).

reference_image_service.py의 generate_single_entity_image를 ReferenceEntityService로 이관.
"""
from __future__ import annotations

from unittest.mock import MagicMock

import pytest

from app.core.errors import AppError
from app.services.reference_entity_service import ReferenceEntityService


@pytest.fixture
def svc():
    """ReferenceEntityService MagicMock 주입 인스턴스."""
    instance = ReferenceEntityService.__new__(ReferenceEntityService)
    instance._db = MagicMock()
    instance._project_id = "p1"
    instance._actor_id = "u1"
    instance._logger = MagicMock()
    return instance


def test_generate_single_entity_raises_when_gemini_key_missing(svc, monkeypatch):
    """gemini_api_key 없고 key_pool count=0이면 AppError(400)."""
    monkeypatch.setattr(
        "app.services.reference_entity_service.settings",
        MagicMock(gemini_api_key=None, gemini_image_model="m"),
    )
    monkeypatch.setattr(
        "app.services.reference_entity_service.gemini_key_count",
        lambda: 0,
    )

    with pytest.raises(AppError) as exc_info:
        svc.generate_single_entity_image("e1")
    assert exc_info.value.code == "image.gemini_key_missing"
    assert exc_info.value.status_code == 400


def test_generate_single_entity_raises_when_entity_missing(svc, monkeypatch):
    """entity_id가 존재하지 않으면 AppError(404)."""
    monkeypatch.setattr(
        "app.services.reference_entity_service.settings",
        MagicMock(gemini_api_key="k", gemini_image_model="m"),
    )
    monkeypatch.setattr(
        "app.services.reference_entity_service.gemini_key_count",
        lambda: 1,
    )
    svc._db.query.return_value.filter.return_value.first.return_value = None

    with pytest.raises(AppError) as exc_info:
        svc.generate_single_entity_image("missing")
    assert exc_info.value.code == "entity.not_found"
    assert exc_info.value.status_code == 404


def test_reference_image_service_facade_injects_entity_svc():
    """ReferenceImageService가 _entity_svc를 주입하고 delegate가 동일 함수 호출."""
    from app.services.reference_image_service import ReferenceImageService

    facade = ReferenceImageService.__new__(ReferenceImageService)
    facade._db = MagicMock()
    facade._project_id = "p1"
    facade._actor_id = "u1"
    facade._logger = MagicMock()
    facade._entity_svc = MagicMock(spec=ReferenceEntityService)

    facade.generate_single_entity_image("e1", custom_prompt="prompt", ip="1.2.3.4")
    facade._entity_svc.generate_single_entity_image.assert_called_once_with(
        "e1", custom_prompt="prompt", ip="1.2.3.4",
    )


def test_reference_image_service_constructor_wires_entity_svc():
    """ReferenceImageService(__init__)가 실제 ReferenceEntityService 인스턴스를 주입한다."""
    from app.services.reference_image_service import ReferenceImageService

    db = MagicMock()
    facade = ReferenceImageService(db=db, project_id="p1", actor_id="u1")

    assert isinstance(facade._entity_svc, ReferenceEntityService)
    assert facade._entity_svc._db is db
    assert facade._entity_svc._project_id == "p1"
    assert facade._entity_svc._actor_id == "u1"
    assert facade._entity_svc._logger is facade._logger
