from collections.abc import Callable
from os import PathLike
from typing import Any, ClassVar, final
from cramjam import Buffer, BufferInput, BufferOutput

@final
class Filter:
    NoFilter: ClassVar[Filter]
    Shuffle: ClassVar[Filter]
    BitShuffle: ClassVar[Filter]
    Delta: ClassVar[Filter]
    TruncPrec: ClassVar[Filter]
    LastFilter: ClassVar[Filter]
    LastRegisteredFilter: ClassVar[Filter]

@final
class CLevel:
    Zero: ClassVar[CLevel]
    One: ClassVar[CLevel]
    Two: ClassVar[CLevel]
    Three: ClassVar[CLevel]
    Four: ClassVar[CLevel]
    Five: ClassVar[CLevel]
    Six: ClassVar[CLevel]
    Seven: ClassVar[CLevel]
    Eight: ClassVar[CLevel]
    Nine: ClassVar[CLevel]

@final
class Codec:
    BloscLz: ClassVar[Codec]
    LZ4: ClassVar[Codec]
    LZ4HC: ClassVar[Codec]
    ZLIB: ClassVar[Codec]
    ZSTD: ClassVar[Codec]
    LastCodec: ClassVar[Codec]
    LastRegisteredCodec: ClassVar[Codec]

def compress(
    input: BufferInput,
    output_len: int | None = None,
    typesize: int | None = None,
    clevel: CLevel | None = None,
    filter: Filter | None = None,
    codec: Codec | None = None,
    nthreads: int | None = None,
) -> Buffer: ...
def compress_into(
    input: BufferInput,
    output: BufferOutput,
    typesize: int | None = None,
    clevel: CLevel | None = None,
    filter: Filter | None = None,
    codec: Codec | None = None,
    nthreads: int | None = None,
) -> int: ...
def decompress(input: BufferInput, output_len: int | None = None) -> Buffer: ...
def decompress_into(input: BufferInput, output: BufferOutput) -> int: ...
def decompress_chunk(data: BufferInput, output_len: int | None = None) -> Buffer: ...
def decompress_chunk_into(input: BufferInput, output: BufferOutput) -> int: ...
def compress_chunk(
    data: BufferInput,
    typesize: int | None = None,
    clevel: CLevel | None = None,
    filter: Filter | None = None,
    codec: Codec | None = None,
) -> Buffer: ...
def compress_chunk_into(
    input: BufferInput,
    output: BufferOutput,
    typesize: int | None = None,
    clevel: CLevel | None = None,
    filter: Filter | None = None,
    codec: Codec | None = None,
) -> int: ...
def set_nthreads(n: int) -> int: ...
def get_nthreads() -> int: ...
def get_version() -> str: ...
def max_compressed_len(len_bytes: int) -> int: ...

class Compressor:
    def __init__(
        self,
        path: str | None = None,
        typesize: int | None = None,
        clevel: CLevel | None = None,
        filter: Filter | None = None,
        codec: Codec | None = None,
        nthreads: int | None = None,
    ) -> None: ...
    def compress(self, input: BufferInput) -> int: ...
    def flush(self) -> Buffer: ...
    def finish(self) -> Buffer: ...

class Decompressor:
    def __init__(self) -> None: ...
    def len(self) -> int: ...
    def decompress(self, input: BufferInput) -> int: ...
    def flush(self) -> Buffer: ...
    def finish(self) -> Buffer: ...
    def __len__(self) -> int: ...
    def __contains__(self, x: BufferInput) -> bool: ...
    def __repr__(self) -> str: ...
    def __bool__(self) -> bool: ...

class Chunk:
    @classmethod
    def compress(
        cls,
        src: BufferInput,
        typesize: int | None = None,
        clevel: CLevel | None = None,
        filter: Filter | None = None,
        codec: Codec | None = None,
    ) -> Chunk: ...
    def decompress(self) -> Buffer: ...
    def raw(self) -> bytes: ...
    def __repr__(self) -> str: ...

class SChunk:
    def __init__(
        self,
        path: str | None = None,
        typesize: int | None = None,
        clevel: CLevel | None = None,
        filter: Filter | None = None,
        codec: Codec | None = None,
        nthreads: int | None = None,
        from_bytes_cb: Callable[[Buffer], Any] | None = None,
        to_bytes_cb: Callable[[Any], BufferInput] | None = None,
    ) -> None: ...
    @classmethod
    def from_compressor(cls, compressor: Compressor) -> SChunk: ...
    def as_compressor(self) -> Compressor: ...
    def get_slice_buffer(self, start: int, stop: int) -> Buffer: ...
    @property
    def typesize(self) -> int: ...
    @property
    def nbytes(self) -> int: ...
    @property
    def cbytes(self) -> int: ...
    @property
    def nchunks(self) -> int: ...
    @property
    def compression_ratio(self) -> float: ...
    @property
    def path(self) -> PathLike[str] | None: ...
    def append_buffer(self, buf: Any) -> int: ...
    def decompress_chunk(self, nchunk: int) -> Any: ...
    def get_chunk(self, nchunk: int) -> Chunk: ...
    def frame(self) -> bytes: ...
    def len(self) -> int: ...
    def __len__(self) -> int: ...
    def __getitem__(self, key: slice) -> Any: ...
    def __setitem__(self, key: slice, buf: Any) -> None: ...
    def __repr__(self) -> str: ...
