"""数据库健康、清理、备份与离线还原的统一应用门面。"""

from __future__ import annotations

from collections.abc import Callable
from typing import TYPE_CHECKING, Any, Optional, Protocol, TypeVar

if TYPE_CHECKING:
    from app.application.backup import (
        BackupArtifact,
        BackupVerification,
        DatabaseBackupService,
    )
    from app.application.maintenance import DataCleanupService


DatabaseProbe = Callable[[], Optional[str]]
T = TypeVar("T")


class AsyncDatabaseExecutor(Protocol):
    """让异步业务调用同步短事务而不阻塞事件循环。"""

    async def run(self, operation: Callable[[], T]) -> T:
        """等待数据库操作完成提交或回滚，并返回执行结果。"""
        ...


class DatabaseHealthService:
    """提供不暴露会话实现的数据库探测能力。"""

    def __init__(self, probe: DatabaseProbe) -> None:
        self._probe = probe

    def test(self) -> Optional[str]:
        """执行数据库探测，成功返回空值，失败返回说明。"""
        return self._probe()


class DatabaseGovernance:
    """向宿主入口提供唯一的数据库治理能力入口。"""

    def __init__(
        self,
        *,
        health: DatabaseHealthService,
        cleanup: DataCleanupService,
        backup: DatabaseBackupService,
    ) -> None:
        self._health = health
        self._cleanup = cleanup
        self._backup = backup

    def test(self) -> Optional[str]:
        """探测当前活动数据库。"""
        return self._health.test()

    def cleanup(
        self,
        *,
        batch_size: int | None = None,
        progress_callback: Callable[..., None] | None = None,
    ) -> dict[str, Any]:
        """按当前配置执行数据表清理。"""
        return self._cleanup.execute(
            batch_size=batch_size,
            progress_callback=progress_callback,
        )

    def create_backup(self) -> BackupArtifact:
        """创建一个当前活动数据库的一致备份。"""
        return self._backup.create()

    def list_backups(self) -> tuple[BackupArtifact, ...]:
        """列出受管数据库备份文件。"""
        return self._backup.list()

    def verify_backup(self, name: str) -> BackupVerification:
        """校验一个受管数据库备份文件。"""
        return self._backup.verify(name)

    def restore_backup(self, name: str) -> BackupArtifact:
        """在离线 CLI 进程中还原一个受管数据库备份。"""
        return self._backup.restore(name)


_DATABASE_GOVERNANCE: list[DatabaseGovernance] = []


def configure_database_governance(governance: DatabaseGovernance) -> None:
    """由启动组合根登记宿主唯一的数据库治理门面。"""
    _DATABASE_GOVERNANCE.clear()
    _DATABASE_GOVERNANCE.append(governance)


def get_database_governance() -> DatabaseGovernance:
    """返回启动阶段登记的数据库治理门面。"""
    if not _DATABASE_GOVERNANCE:
        raise RuntimeError("数据库治理服务尚未配置")
    return _DATABASE_GOVERNANCE[0]
