"""Tests for transcription.app."""

from contextlib import asynccontextmanager

import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient

from transcription.app import create_app


@pytest.mark.unit
class TestAppFactory:
    """Verify FastAPI app factory wiring."""

    def test_create_app_returns_fastapi_instance(self):
        """create_app returns a FastAPI application instance."""
        app = create_app()
        assert isinstance(app, FastAPI)


@pytest.mark.integration
class TestAppLifespan:
    """Verify startup and shutdown lifecycle behavior."""

    def test_startup_initializes_runtime_dependencies(self, monkeypatch, tmp_path):
        """Startup initializes logging, schema, directories, and worker resources."""
        calls = []

        monkeypatch.setattr("transcription.app.configure_logging", lambda _settings: calls.append("logging"))

        async def _create_all(**_kwargs):
            calls.append("schema")

        monkeypatch.setattr("transcription.app.create_all", _create_all)
        monkeypatch.setattr(
            "transcription.app.initialize_database_runtime",
            lambda **_kwargs: type("_Runtime", (), {"engine": object(), "session_factory": object()})(),
        )

        async def _dispose_runtime():
            calls.append("dispose_db")

        monkeypatch.setattr("transcription.app.dispose_database_runtime", _dispose_runtime)

        async def _recover_stale(_app):
            calls.append("recover")

        monkeypatch.setattr("transcription.app._recover_stale_processing_jobs", _recover_stale)

        @asynccontextmanager
        async def _worker_lifespan(**_kwargs):
            calls.append("worker_start")
            yield object(), object()
            calls.append("worker_stop")

        monkeypatch.setattr("transcription.app.worker_consumer_lifespan", _worker_lifespan)

        class _Settings:
            should_bootstrap_schema = True
            upload_dir = tmp_path / "uploads"
            prompt_dir = tmp_path / "prompts"

        monkeypatch.setattr("transcription.app.get_settings", lambda: _Settings())

        app = create_app()
        with TestClient(app):
            pass

        assert "logging" in calls
        assert "schema" in calls
        assert "recover" in calls
        assert "worker_start" in calls
        assert "worker_stop" in calls
        assert "dispose_db" in calls
        assert _Settings.upload_dir.exists()
        assert _Settings.prompt_dir.exists()

    def test_shutdown_stops_worker_resources(self, monkeypatch, tmp_path):
        """Shutdown signals and stops worker resources cleanly."""
        calls = []

        monkeypatch.setattr("transcription.app.configure_logging", lambda _settings: calls.append("logging"))

        async def _create_all(**_kwargs):
            calls.append("schema")

        monkeypatch.setattr("transcription.app.create_all", _create_all)
        monkeypatch.setattr(
            "transcription.app.initialize_database_runtime",
            lambda **_kwargs: type("_Runtime", (), {"engine": object(), "session_factory": object()})(),
        )

        async def _dispose_runtime():
            calls.append("dispose_db")

        monkeypatch.setattr("transcription.app.dispose_database_runtime", _dispose_runtime)

        async def _recover_stale(_app):
            calls.append("recover")

        monkeypatch.setattr("transcription.app._recover_stale_processing_jobs", _recover_stale)

        @asynccontextmanager
        async def _worker_lifespan(**_kwargs):
            calls.append("worker_start")
            yield object(), object()
            calls.append("worker_stop")

        monkeypatch.setattr("transcription.app.worker_consumer_lifespan", _worker_lifespan)

        class _Settings:
            should_bootstrap_schema = True
            upload_dir = tmp_path / "uploads"
            prompt_dir = tmp_path / "prompts"

        monkeypatch.setattr("transcription.app.get_settings", lambda: _Settings())

        app = create_app()
        with TestClient(app):
            pass

        assert calls == ["logging", "schema", "recover", "worker_start", "worker_stop", "dispose_db"]
