"""
ZXC - High-performance lossless compression

Copyright (c) 2025-2026 Bertrand Lebonnois and contributors.
SPDX-License-Identifier: BSD-3-Clause
"""

from typing import Protocol, Optional

# ---------- constants ----------
LEVEL_FASTEST: int
LEVEL_FAST: int
LEVEL_DEFAULT: int
LEVEL_BALANCED: int
LEVEL_COMPACT: int

# ---------- types ----------
class FileLike(Protocol):
    """File-like object with a file descriptor.
    
    Note:
        This excludes in-memory streams like io.BytesIO.
        Use real file objects or objects wrapping OS file descriptors.
    """
    def fileno(self) -> int: ...
    def readable(self) -> bool: ...
    def writable(self) -> bool: ...

# ---------- functions ----------
def compress(
    data: bytes,
    level: int = LEVEL_DEFAULT,
    checksum: bool = False
) -> bytes: ...

def decompress(
    data: bytes,
    decompress_size: Optional[int] = None,
    checksum: bool = False
) -> bytes: ...

def stream_compress(
    src: FileLike,
    dst: FileLike,
    n_threads: int = 0,
    level: int = LEVEL_DEFAULT,
    checksum: bool = False
) -> int: ...

def stream_decompress(
    src: FileLike,
    dst: FileLike,
    n_threads: int = 0,
    checksum: bool = False
) -> int: ...

def get_decompressed_size(data: bytes) -> int: ...

def min_level() -> int: ...
def max_level() -> int: ...
def default_level() -> int: ...
def library_version() -> str: ...

# ---------- push streaming ----------
class CStream:
    """Push-based, single-threaded compression stream."""
    def __init__(self, level: int = LEVEL_DEFAULT, checksum: bool = False, block_size: int = 0) -> None: ...
    def compress(self, data: bytes) -> bytes: ...
    def end(self) -> bytes: ...
    @property
    def in_size(self) -> int: ...
    @property
    def out_size(self) -> int: ...
    def close(self) -> None: ...
    def __enter__(self) -> "CStream": ...
    def __exit__(self, exc_type, exc, tb) -> bool: ...

class DStream:
    """Push-based, single-threaded decompression stream."""
    def __init__(self, checksum: bool = False) -> None: ...
    def decompress(self, data: bytes) -> bytes: ...
    @property
    def finished(self) -> bool: ...
    @property
    def in_size(self) -> int: ...
    @property
    def out_size(self) -> int: ...
    def close(self) -> None: ...
    def __enter__(self) -> "DStream": ...
    def __exit__(self, exc_type, exc, tb) -> bool: ...

# ---------- io.RawIOBase adapters ----------
import io as _io
from typing import IO

def detect_zxc(data: bytes) -> bool: ...

class ZxcReader(_io.RawIOBase):
    """Decompresses a ZXC frame read from a binary file-like object."""
    def __init__(
        self,
        fileobj: IO[bytes],
        *,
        checksum: bool = False,
        buffer_size: int = 0,
    ) -> None: ...
    def readable(self) -> bool: ...
    def readinto(self, b: bytearray) -> int: ...
    def close(self) -> None: ...

class ZxcWriter(_io.RawIOBase):
    """Compresses bytes written to it into a binary file-like object."""
    def __init__(
        self,
        fileobj: IO[bytes],
        *,
        level: int = LEVEL_DEFAULT,
        checksum: bool = False,
    ) -> None: ...
    def writable(self) -> bool: ...
    def write(self, b: bytes) -> int: ...
    def close(self) -> None: ...