#  Copyright (c) yibocat 2025 All Rights Reserved
#  Python: 3.12.7
#  Date: 2025/8/18 18:23
#  Author: yibow
#  Email: yibocat@yeah.net
#  Software: AxisFuzzy
import threading
from contextlib import contextmanager
from typing import Optional, Dict, Type, List, Any, TypeVar, Callable
from .base import FuzznumStrategy
from .backend import FuzzarrayBackend

T = TypeVar('T', bound=FuzznumStrategy)
B = TypeVar('B', bound=FuzzarrayBackend)

class FuzznumRegistry:

    strategies: Dict[str, Type[FuzznumStrategy]]
    backends: Dict[str, Type[FuzzarrayBackend]]

    _instance: Optional['FuzznumRegistry']
    _lock: threading.RLock
    _initialized: bool

    _registration_history: List[Dict[str, Any]]
    _registration_stats: Dict[str, Any]
    _transaction_stack: List[Dict[str, Any]]
    _in_transaction: bool
    _observers: List[Callable[[str, Dict[str, Any]], None]]

    def __new__(cls, *args, **kwargs) -> 'FuzznumRegistry': ...
    def __init__(self) -> None: ...

    def _init_registry(self) -> None: ...

    @contextmanager
    def transaction(self): ...
    def _create_snapshot(self) -> Dict[str, Any]: ...
    def _restore_snapshot(self, snapshot: Dict[str, Any]) -> None: ...

    def add_observer(self, observer: Callable[[str, Dict[str, Any]], None]) -> None: ...
    def remove_observer(self, observer: Callable[[str, Dict[str, Any]], None]) -> None: ...
    def _notify_observers(self, event_type: str, event_data: Dict[str, Any]) -> None: ...

    def register_strategy(self, strategy: Type[FuzznumStrategy]) -> Dict[str, Any]: ...
    def register_backend(self, backend: Type[FuzzarrayBackend]) -> Dict[str, Any]: ...
    def register(self,
                 strategy: Optional[Type[FuzznumStrategy]] = ...,
                 backend: Optional[Type[FuzzarrayBackend]] = ...) -> Dict[str, Any]: ...
    def batch_register(self, registrations: List[Dict[str, Any]]) -> Dict[str, Dict[str, Any]]: ...
    def unregister(self, mtype: str,
                   remove_strategy: bool = ...,
                   remove_backend: bool = ...) -> Dict[str, Any]: ...

    @staticmethod
    def _validate_strategy_class(strategy: Type[FuzznumStrategy]) -> None: ...
    @staticmethod
    def _validate_backend_class(backend: Type[FuzzarrayBackend]) -> None: ...

    def get_strategy(self, mtype: str) -> Type[FuzznumStrategy]: ...
    def get_backend(self, mtype: str) -> Type[FuzzarrayBackend]: ...
    def get_registered_mtypes(self) -> Dict[str, Dict[str, Any]]: ...
    def get_statistics(self) -> Dict[str, Any]: ...
    def get_health_status(self) -> Dict[str, Any]: ...

# Key: The decorator needs to return Type[T], not an instance, in a "shape-preserving" manner.
def get_registry_fuzztype() -> FuzznumRegistry: ...
def register_strategy(cls: Type[T]) -> Type[T]: ...
def register_backend(cls: Type[B]) -> Type[B]: ...
def register_fuzztype(strategy: Optional[Type[FuzznumStrategy]] = ...,
                      backend: Optional[Type[FuzzarrayBackend]] = ...) -> Dict[str, Any]: ...

