"""Integration tests verifying perform_nfo_repair_scan is wired into folder scan
and NOT called during FastAPI lifespan startup.

These tests confirm that:
1. FolderScanService.run_folder_scan calls perform_nfo_repair_scan.
2. perform_nfo_repair_scan is NOT imported or called in fastapi_app.py lifespan.
3. Series with incomplete NFO files are queued via asyncio.create_task.
"""
from unittest.mock import AsyncMock, MagicMock, call, patch

import pytest


class TestNfoRepairScanNotCalledOnStartup:
    """Verify perform_nfo_repair_scan is NOT invoked during FastAPI lifespan startup."""

    def test_perform_nfo_repair_scan_not_imported_in_lifespan(self):
        """fastapi_app.py lifespan must not import or call perform_nfo_repair_scan."""
        import importlib

        source = importlib.util.find_spec("src.server.fastapi_app").origin
        with open(source, "r", encoding="utf-8") as fh:
            content = fh.read()

        assert "perform_nfo_repair_scan" not in content, (
            "perform_nfo_repair_scan must NOT be imported or called in fastapi_app.py"
        )


class TestNfoRepairScanCalledInFolderScan:
    """Verify perform_nfo_repair_scan is invoked from FolderScanService."""

    def test_perform_nfo_repair_scan_imported_in_folder_scan_service(self):
        """folder_scan_service.py imports perform_nfo_repair_scan."""
        import importlib

        source = importlib.util.find_spec("src.server.services.folder_scan_service").origin
        with open(source, "r", encoding="utf-8") as fh:
            content = fh.read()

        assert "perform_nfo_repair_scan" in content, (
            "perform_nfo_repair_scan must be imported in folder_scan_service.py"
        )

    def test_perform_nfo_repair_scan_called_in_run_folder_scan(self):
        """perform_nfo_repair_scan must be called inside run_folder_scan."""
        import importlib

        source = importlib.util.find_spec("src.server.services.folder_scan_service").origin
        with open(source, "r", encoding="utf-8") as fh:
            content = fh.read()

        run_folder_scan_pos = content.find("def run_folder_scan")
        # Find the call inside the method body (after the import line)
        repair_scan_call_pos = content.find("await perform_nfo_repair_scan(background_loader=None)")

        assert run_folder_scan_pos != -1, "run_folder_scan method not found"
        assert repair_scan_call_pos != -1, "perform_nfo_repair_scan call not found"
        assert repair_scan_call_pos > run_folder_scan_pos, (
            "perform_nfo_repair_scan must be called INSIDE run_folder_scan"
        )


class TestNfoRepairScanIntegrationWithBackgroundLoader:
    """Integration test: incomplete NFO series are queued via background_loader."""

    @pytest.mark.asyncio
    async def test_incomplete_nfo_series_scheduled_for_repair(self, tmp_path):
        """Series whose tvshow.nfo is missing required tags are scheduled via asyncio.create_task."""
        from src.server.services.folder_scan_service import perform_nfo_repair_scan

        series_dir = tmp_path / "IncompleteAnime"
        series_dir.mkdir()
        (series_dir / "tvshow.nfo").write_text(
            "<tvshow><title>IncompleteAnime</title></tvshow>"
        )

        mock_settings = MagicMock()
        mock_settings.tmdb_api_key = "test-key"
        mock_settings.anime_directory = str(tmp_path)

        mock_repair_service = AsyncMock()
        mock_repair_service.repair_series = AsyncMock(return_value=True)

        with patch(
            "src.server.services.folder_scan_service._settings", mock_settings
        ), patch(
            "src.core.services.nfo_repair_service.nfo_needs_repair",
            return_value=True,
        ), patch(
            "src.core.services.nfo_factory.NFOServiceFactory"
        ) as mock_factory, patch(
            "src.core.services.nfo_repair_service.NfoRepairService",
            return_value=mock_repair_service,
        ), patch(
            "asyncio.create_task"
        ) as mock_create_task:
            mock_factory.return_value.create.return_value = MagicMock()
            await perform_nfo_repair_scan(background_loader=AsyncMock())

        mock_create_task.assert_called_once()

    @pytest.mark.asyncio
    async def test_complete_nfo_series_not_scheduled(self, tmp_path):
        """Series whose tvshow.nfo has all required tags are not scheduled for repair."""
        from src.server.services.folder_scan_service import perform_nfo_repair_scan

        series_dir = tmp_path / "CompleteAnime"
        series_dir.mkdir()
        (series_dir / "tvshow.nfo").write_text(
            "<tvshow><title>CompleteAnime</title></tvshow>"
        )

        mock_settings = MagicMock()
        mock_settings.tmdb_api_key = "test-key"
        mock_settings.anime_directory = str(tmp_path)

        with patch(
            "src.server.services.folder_scan_service._settings", mock_settings
        ), patch(
            "src.core.services.nfo_repair_service.nfo_needs_repair",
            return_value=False,
        ), patch(
            "src.core.services.nfo_factory.NFOServiceFactory"
        ) as mock_factory, patch(
            "asyncio.create_task"
        ) as mock_create_task:
            mock_factory.return_value.create.return_value = MagicMock()
            await perform_nfo_repair_scan(background_loader=AsyncMock())

        mock_create_task.assert_not_called()
