import random
import timeit
from _typeshed import ReadableBuffer
from collections.abc import Iterable
from hmac import compare_digest
from typing import Final, Literal, SupportsBytes, SupportsIndex, overload

from passlib.utils.compat import JYTHON as JYTHON

__all__ = [
    "JYTHON",
    "sys_bits",
    "unix_crypt_schemes",
    "rounds_cost_values",
    "consteq",
    "saslprep",
    "xor_bytes",
    "render_bytes",
    "is_same_codec",
    "is_ascii_safe",
    "to_bytes",
    "to_unicode",
    "to_native_str",
    "has_crypt",
    "test_crypt",
    "safe_crypt",
    "tick",
    "rng",
    "getrandbytes",
    "getrandstr",
    "generate_password",
    "is_crypt_handler",
    "is_crypt_context",
    "has_rounds_info",
    "has_salt_info",
]

sys_bits: Final[int]
unix_crypt_schemes: list[str]
rounds_cost_values: Final[list[str]]

class SequenceMixin:
    def __getitem__(self, idx): ...
    def __iter__(self): ...
    def __len__(self) -> int: ...
    def __eq__(self, other): ...
    def __ne__(self, other): ...

consteq = compare_digest

def str_consteq(left: str | bytes, right: str | bytes) -> bool: ...
def splitcomma(source: str, sep: str = ",") -> list[str]: ...
def saslprep(source: str, param: str = "value") -> str: ...
def render_bytes(source: str | bytes, *args: str | bytes) -> bytes: ...
def bytes_to_int(value: Iterable[SupportsIndex] | SupportsBytes | ReadableBuffer) -> int: ...
def int_to_bytes(value: int, count: SupportsIndex) -> bytes: ...
def xor_bytes(
    left: Iterable[SupportsIndex] | SupportsBytes | ReadableBuffer,
    right: Iterable[SupportsIndex] | SupportsBytes | ReadableBuffer,
) -> bytes: ...
def repeat_string(source: str | bytes, size: int) -> str | bytes: ...
def is_ascii_codec(codec: str) -> bool: ...
def is_same_codec(left: str, right: str) -> bool: ...
def is_ascii_safe(source: str | bytes) -> bool: ...
def to_bytes(source: str | bytes, encoding: str = "utf-8", param: str = "value", source_encoding: str | None = None) -> bytes: ...
def to_unicode(source: str | bytes, encoding: str = "utf-8", param: str = "value") -> str: ...
def to_native_str(source: str | bytes, encoding: str = "utf-8", param: str = "value") -> str: ...

has_crypt: bool

def safe_crypt(secret: str | bytes, hash: str | bytes) -> str | None: ...
def test_crypt(secret: str | bytes, hash: str) -> bool: ...

timer = timeit.default_timer
tick = timer
rng: random.Random

@overload
def getrandbytes(rng: random.Random, count: None) -> Literal[b""]: ...
@overload
def getrandbytes(rng: random.Random, count) -> bytes: ...
def getrandstr(rng: random.Random, charset: str, count: int) -> str: ...
def generate_password(size: int = 10, charset: str = ...) -> str: ...
def is_crypt_handler(obj) -> bool: ...
def is_crypt_context(obj) -> bool: ...
def has_rounds_info(handler) -> bool: ...
def has_salt_info(handler) -> bool: ...
