from types import TracebackType
from typing import IO, TYPE_CHECKING, Callable, Literal, Self

if TYPE_CHECKING:
    from threading import RLock

    from logbook.base import LogLevel, LogRecord

from _typeshed import Incomplete
from logbook.base import LogRecord

class Handler:
    blackhole: bool
    level: LogLevel
    formatter: Formatter | None
    filter: LogFilter | None
    bubble: bool
    stack_manager: Incomplete

    def __init__(self, level: int | str = ..., filter: LogFilter | None = ..., bubble: bool = False) -> None: ...
    @property
    def level_name(self) -> str: ...
    def format(self, record: LogRecord) -> str: ...
    def should_handle(self, record: LogRecord) -> bool: ...
    def handle(self, record: LogRecord) -> bool: ...
    def emit(self, record: LogRecord) -> None: ...
    def emit_batch(self, records: list[LogRecord], reason: str) -> None: ...
    def close(self) -> None: ...
    def handle_error(
        self, record: LogRecord, exc_info: tuple[type[BaseException], BaseException, TracebackType]
    ) -> None: ...
    def push_application(self) -> None: ...
    def pop_application(self) -> None: ...
    def push_context(self) -> None: ...
    def pop_context(self) -> None: ...
    def __enter__(self) -> Self: ...
    def __exit__(
        self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None
    ) -> None: ...

class Formatter:
    def __call__(self, record: LogRecord, handler: Handler) -> str: ...

class StringFormatterHandlerMixin: ...

class StreamHandler(Handler, StringFormatterHandlerMixin):
    stream: IO[str]
    lock: RLock
    def __init__(
        self,
        stream: Incomplete = ...,
        level: int | str = 0,
        format_string: str = '',
        encoding: str | None = None,
        filter: 'LogFilter | None' = None,
        bubble: bool = False,
    ) -> None: ...
    def ensure_stream_is_open(self) -> None: ...
    def encode(self, msg: str) -> str: ...
    def write(self, item: str) -> None: ...
    def should_flush(self) -> Literal[True]: ...
    def flush(self) -> None: ...

type LogFilter = Callable[[LogRecord, Handler], bool]

class StderrHandler(StreamHandler):
    def __init__(
        self, level: int | str = 0, format_string: str = '', filter: LogFilter | None = None, bubble: bool = False
    ) -> None: ...

__all__ = [
    'Handler',
    'Formatter',
    'StringFormatterHandlerMixin',
    'StreamHandler',
    'StderrHandler',
    'LogFilter',
]
