from collections.abc import Callable
from ctypes import c_void_p
from typing import Any, Final, Literal, Self, final, overload
from weakref import ReferenceType

from ._typing import _IntLike
from .constants import MessageType

# Environment SubSystem
@final
class EnvironmentData: ...

class EnvironmentPolicy:
    def on_policy_registered(self, special_api: EnvironmentPolicyAPI) -> None: ...
    def on_policy_cleared(self) -> None: ...
    def get_current_environment(self) -> EnvironmentData | None: ...
    def set_environment(self, environment: EnvironmentData | None) -> EnvironmentData | None: ...
    def is_alive(self, environment: EnvironmentData) -> bool: ...

@final
class StandaloneEnvironmentPolicy:
    def on_policy_registered(self, api: EnvironmentPolicyAPI) -> None: ...
    def on_policy_cleared(self) -> None: ...
    def get_current_environment(self) -> EnvironmentData: ...
    def set_environment(self, environment: EnvironmentData | None) -> EnvironmentData: ...
    def is_alive(self, environment: EnvironmentData) -> bool: ...
    def _on_log_message(self, level: MessageType, msg: str) -> None: ...

@final
class VSScriptEnvironmentPolicy:
    def on_policy_registered(self, policy_api: EnvironmentPolicyAPI) -> None: ...
    def on_policy_cleared(self) -> None: ...
    def get_current_environment(self) -> EnvironmentData | None: ...
    def set_environment(self, environment: EnvironmentData | None) -> EnvironmentData | None: ...
    def is_alive(self, environment: EnvironmentData) -> bool: ...

@final
class EnvironmentPolicyAPI:
    def wrap_environment(self, environment_data: EnvironmentData) -> Environment: ...
    def create_environment(self, flags: _IntLike = 0) -> EnvironmentData: ...
    def set_logger(self, env: EnvironmentData, logger: Callable[[int, str], None]) -> None: ...
    def get_vapoursynth_api(self, version: int) -> c_void_p: ...
    def get_core_ptr(self, environment_data: EnvironmentData) -> c_void_p: ...
    def destroy_environment(self, env: EnvironmentData) -> None: ...
    def unregister_policy(self) -> None: ...

def register_policy(policy: EnvironmentPolicy) -> None: ...
def has_policy() -> bool: ...
def register_on_destroy(callback: Callable[..., None]) -> None: ...
def unregister_on_destroy(callback: Callable[..., None]) -> None: ...
def _try_enable_introspection(version: int | None = None) -> bool: ...
@final
class _FastManager:
    def __enter__(self) -> None: ...
    def __exit__(self, *_: object) -> None: ...

class Environment:
    env: Final[ReferenceType[EnvironmentData]]
    def __repr__(self) -> str: ...
    @overload
    def __eq__(self, other: Environment) -> bool: ...
    @overload
    def __eq__(self, other: object) -> bool: ...
    @property
    def alive(self) -> bool: ...
    @property
    def single(self) -> bool: ...
    @classmethod
    def is_single(cls) -> bool: ...
    @property
    def env_id(self) -> int: ...
    @property
    def active(self) -> bool: ...
    def copy(self) -> Self: ...
    def use(self) -> _FastManager: ...

class Local:
    def __getattr__(self, key: str) -> Any: ...
    def __setattr__(self, key: str, value: Any) -> None: ...
    def __delattr__(self, key: str) -> None: ...

def get_current_environment() -> Environment: ...

class CoreTimings:
    def __repr__(self) -> str: ...
    def __str__(self) -> str: ...
    @property
    def enabled(self) -> bool: ...
    @enabled.setter
    def enabled(self, enabled: bool) -> bool: ...
    @property
    def freed_nodes(self) -> bool: ...
    @freed_nodes.setter
    def freed_nodes(self, value: Literal[0]) -> bool: ...
