from __future__ import annotations

from pathlib import Path

import pytest

from py.services.example_images_cleanup_service import ExampleImagesCleanupService
from py.services.service_registry import ServiceRegistry
from py.services.settings_manager import get_settings_manager


class StubScanner:
    def __init__(self, valid_hashes: set[str] | None = None) -> None:
        self._valid_hashes = valid_hashes or set()

    def has_hash(self, value: str) -> bool:
        return value in self._valid_hashes


@pytest.mark.asyncio
async def test_cleanup_moves_empty_and_orphaned(tmp_path, monkeypatch):
    service = ExampleImagesCleanupService()

    settings_manager = get_settings_manager()
    previous_path = settings_manager.get('example_images_path')
    settings_manager.settings['example_images_path'] = str(tmp_path)

    try:
        empty_folder = tmp_path / 'empty_folder'
        empty_folder.mkdir()

        orphan_hash = 'a' * 64
        orphan_folder = tmp_path / orphan_hash
        orphan_folder.mkdir()
        (orphan_folder / 'image.png').write_text('data', encoding='utf-8')

        valid_hash = 'b' * 64
        valid_folder = tmp_path / valid_hash
        valid_folder.mkdir()
        (valid_folder / 'image.png').write_text('data', encoding='utf-8')

        matching_scanner = StubScanner({valid_hash})
        empty_scanner = StubScanner()

        async def get_matching_scanner(*_args, **_kwargs):
            return matching_scanner

        async def get_empty_scanner(*_args, **_kwargs):
            return empty_scanner

        monkeypatch.setattr(ServiceRegistry, 'get_lora_scanner', get_matching_scanner)
        monkeypatch.setattr(ServiceRegistry, 'get_checkpoint_scanner', get_empty_scanner)
        monkeypatch.setattr(ServiceRegistry, 'get_embedding_scanner', get_empty_scanner)

        result = await service.cleanup_example_image_folders()

        deleted_bucket = Path(str(result['deleted_root']))
        assert result['success'] is True
        assert result['moved_total'] == 2
        assert not empty_folder.exists()
        assert not (deleted_bucket / 'empty_folder').exists()
        assert (deleted_bucket / orphan_hash).exists()
        assert not orphan_folder.exists()
        assert valid_folder.exists()

    finally:
        if previous_path is None:
            settings_manager.settings.pop('example_images_path', None)
        else:
            settings_manager.settings['example_images_path'] = previous_path


@pytest.mark.asyncio
async def test_cleanup_handles_missing_path(monkeypatch):
    service = ExampleImagesCleanupService()

    settings_manager = get_settings_manager()
    previous_path = settings_manager.get('example_images_path')
    settings_manager.settings.pop('example_images_path', None)

    try:
        result = await service.cleanup_example_image_folders()
    finally:
        if previous_path is not None:
            settings_manager.settings['example_images_path'] = previous_path

    assert result['success'] is False
    assert result['error_code'] == 'path_not_configured'
