from collections.abc import Callable, Iterator, Mapping
from typing import Any, NamedTuple

from .helpers import StableDict

def want_bytes(v: Any, *, errors: str = ...) -> bytes: ...
def chunks_contents_equal(chunks1: Iterator, chunks2: Iterator) -> bool: ...

class PropDict:
    VALID_KEYS: set[str] = ...
    def __init__(self, data_dict: dict = None, internal_dict: dict = None, **kw) -> None: ...
    def as_dict(self) -> StableDict: ...
    def get(self, key: str, default: Any = None) -> Any: ...
    def update(self, d: dict) -> None: ...
    def update_internal(self, d: dict) -> None: ...
    def __contains__(self, key: str) -> bool: ...
    def __eq__(self, other: object) -> bool: ...

class ArchiveItem(PropDict):
    @property
    def version(self) -> int: ...
    @version.setter
    def version(self, val: int) -> None: ...
    @property
    def name(self) -> str: ...
    @name.setter
    def name(self, val: str) -> None: ...
    @property
    def start(self) -> str: ...
    @start.setter
    def start(self, val: str) -> None: ...
    @property
    def end(self) -> str: ...
    @end.setter
    def end(self, val: str) -> None: ...
    @property
    def time(self) -> str: ...
    @time.setter
    def time(self, val: str) -> None: ...
    @property
    def time_end(self) -> str: ...
    @time_end.setter
    def time_end(self, val: str) -> None: ...
    @property
    def username(self) -> str: ...
    @username.setter
    def username(self, val: str) -> None: ...
    @property
    def hostname(self) -> str: ...
    @hostname.setter
    def hostname(self, val: str) -> None: ...
    @property
    def comment(self) -> str: ...
    @comment.setter
    def comment(self, val: str) -> None: ...
    @property
    def tags(self) -> list[str]: ...
    @tags.setter
    def tags(self, val: list[str]) -> None: ...
    @property
    def chunker_params(self) -> tuple: ...
    @chunker_params.setter
    def chunker_params(self, val: tuple) -> None: ...
    @property
    def cmdline(self) -> list[str]: ...
    @cmdline.setter
    def cmdline(self, val: list[str]) -> None: ...
    @property
    def recreate_cmdline(self) -> list[str]: ...
    @recreate_cmdline.setter
    def recreate_cmdline(self, val: list[str]) -> None: ...
    @property
    def recreate_args(self) -> Any: ...
    @recreate_args.setter
    def recreate_args(self, val: Any) -> None: ...
    @property
    def recreate_partial_chunks(self) -> Any: ...
    @recreate_partial_chunks.setter
    def recreate_partial_chunks(self, val: Any) -> None: ...
    @property
    def recreate_source_id(self) -> Any: ...
    @recreate_source_id.setter
    def recreate_source_id(self, val: Any) -> None: ...
    @property
    def nfiles(self) -> int: ...
    @nfiles.setter
    def nfiles(self, val: int) -> None: ...
    @property
    def nfiles_parts(self) -> int: ...
    @nfiles_parts.setter
    def nfiles_parts(self, val: int) -> None: ...
    @property
    def size(self) -> int: ...
    @size.setter
    def size(self, val: int) -> None: ...
    @property
    def size_parts(self) -> int: ...
    @size_parts.setter
    def size_parts(self, val: int) -> None: ...
    @property
    def csize(self) -> int: ...
    @csize.setter
    def csize(self, val: int) -> None: ...
    @property
    def items(self) -> list: ...
    @items.setter
    def items(self, val: list) -> None: ...
    @property
    def item_ptrs(self) -> list: ...
    @item_ptrs.setter
    def item_ptrs(self, val: list) -> None: ...

class ChunkListEntry(NamedTuple):
    id: bytes
    size: int

class Item(PropDict):
    @property
    def path(self) -> str: ...
    @path.setter
    def path(self, val: str) -> None: ...
    @property
    def source(self) -> str: ...
    @source.setter
    def source(self, val: str) -> None: ...
    def is_dir(self) -> bool: ...
    def is_link(self) -> bool: ...
    def _is_type(self, typetest: Callable) -> bool: ...
    @classmethod
    def create_deleted(self, path) -> Item: ...
    @property
    def atime(self) -> int: ...
    @atime.setter
    def atime(self, val: int) -> None: ...
    @property
    def ctime(self) -> int: ...
    @ctime.setter
    def ctime(self, val: int) -> None: ...
    @property
    def mtime(self) -> int: ...
    @mtime.setter
    def mtime(self, val: int) -> None: ...
    @property
    def birthtime(self) -> int: ...
    @birthtime.setter
    def birthtime(self, val: int) -> None: ...
    @property
    def xattrs(self) -> StableDict: ...
    @xattrs.setter
    def xattrs(self, val: StableDict) -> None: ...
    @property
    def digests(self) -> StableDict: ...
    @digests.setter
    def digests(self, val: StableDict) -> None: ...
    @property
    def acl_access(self) -> bytes: ...
    @acl_access.setter
    def acl_access(self, val: bytes) -> None: ...
    @property
    def acl_default(self) -> bytes: ...
    @acl_default.setter
    def acl_default(self, val: bytes) -> None: ...
    @property
    def acl_extended(self) -> bytes: ...
    @acl_extended.setter
    def acl_extended(self, val: bytes) -> None: ...
    @property
    def acl_nfs4(self) -> bytes: ...
    @acl_nfs4.setter
    def acl_nfs4(self, val: bytes) -> None: ...
    @property
    def bsdflags(self) -> int: ...
    @bsdflags.setter
    def bsdflags(self, val: int) -> None: ...
    @property
    def chunks(self) -> list: ...
    @chunks.setter
    def chunks(self, val: list) -> None: ...
    @property
    def chunks_healthy(self) -> list: ...
    @chunks_healthy.setter
    def chunks_healthy(self, val: list) -> None: ...
    @property
    def deleted(self) -> bool: ...
    @deleted.setter
    def deleted(self, val: bool) -> None: ...
    @property
    def hlid(self) -> bytes: ...
    @hlid.setter
    def hlid(self, val: bytes) -> None: ...
    # legacy borg1 on-disk key, only read when transferring borg1 archives
    @property
    def hardlink_master(self) -> bool: ...
    @hardlink_master.setter
    def hardlink_master(self, val: bool) -> None: ...
    @property
    def uid(self) -> int: ...
    @uid.setter
    def uid(self, val: int) -> None: ...
    @property
    def gid(self) -> int: ...
    @gid.setter
    def gid(self, val: int) -> None: ...
    @property
    def user(self) -> str: ...
    @user.setter
    def user(self, val: str) -> None: ...
    @property
    def group(self) -> str: ...
    @group.setter
    def group(self, val: str) -> None: ...
    @property
    def mode(self) -> int: ...
    @mode.setter
    def mode(self, val: int) -> None: ...
    @property
    def rdev(self) -> int: ...
    @rdev.setter
    def rdev(self, val: int) -> None: ...
    @property
    def nlink(self) -> int: ...
    @nlink.setter
    def nlink(self, val: int) -> None: ...
    @property
    def inode(self) -> int: ...
    @inode.setter
    def inode(self, val: int) -> None: ...
    @property
    def size(self) -> int: ...
    @size.setter
    def size(self, val: int) -> None: ...
    def get_size(self, *, memorize: bool = ..., from_chunks: bool = ..., consider_ids: list[bytes] = ...) -> int: ...
    @property
    def part(self) -> int: ...
    @part.setter
    def part(self, val: int) -> None: ...

class ManifestItem(PropDict):
    @property
    def version(self) -> int: ...
    @version.setter
    def version(self, val: int) -> None: ...
    @property
    def timestamp(self) -> str: ...
    @timestamp.setter
    def timestamp(self, val: str) -> None: ...
    @property
    def archives(self) -> Mapping[bytes, dict]: ...
    @archives.setter
    def archives(self, val: Mapping[bytes, dict]) -> None: ...
    @property
    def config(self) -> dict: ...
    @config.setter
    def config(self, val: dict) -> None: ...
    @property
    def item_keys(self) -> tuple: ...
    @item_keys.setter
    def item_keys(self, val: tuple) -> None: ...

class DiffChange:
    diff_type: str
    diff_data: dict[str, Any]
    def __init__(self, diff_type: str, diff_data: dict[str, Any] | None = ...) -> None: ...
    def to_dict(self) -> dict[str, Any]: ...

class ItemDiff:
    path: str
    _item1: Item
    _item2: Item
    _chunk_1: Iterator
    _chunk_2: Iterator
    _numeric_ids: bool
    _can_compare_chunk_ids: bool
    def __init__(
        self,
        path: str,
        item1: Item,
        item2: Item,
        chunk_1: Iterator,
        chunk_2: Iterator,
        numeric_ids: bool = ...,
        can_compare_chunk_ids: bool = ...,
    ) -> None: ...
    def changes(self) -> dict[str, DiffChange]: ...
    def equal(self, content_only: bool = ...) -> bool: ...
    def content(self) -> DiffChange | None: ...
    def ctime(self) -> DiffChange | None: ...
    def mtime(self) -> DiffChange | None: ...
    def mode(self) -> DiffChange | None: ...
    def type(self) -> DiffChange | None: ...
    def owner(self) -> DiffChange | None: ...
    def user(self) -> DiffChange | None: ...
    def group(self) -> DiffChange | None: ...

def chunk_content_equal(chunks_a: Iterator, chunks_b: Iterator) -> bool: ...

class Key(PropDict):
    @property
    def version(self) -> int: ...
    @version.setter
    def version(self, val: int) -> None: ...
    @property
    def chunk_seed(self) -> int: ...
    @chunk_seed.setter
    def chunk_seed(self, val: int) -> None: ...
    @property
    def tam_required(self) -> bool: ...
    @tam_required.setter
    def tam_required(self, val: bool) -> None: ...
    @property
    def enc_hmac_key(self) -> bytes: ...
    @enc_hmac_key.setter
    def enc_hmac_key(self, val: bytes) -> None: ...
    @property
    def enc_key(self) -> bytes: ...
    @enc_key.setter
    def enc_key(self, val: bytes) -> None: ...
    @property
    def id_key(self) -> bytes: ...
    @id_key.setter
    def id_key(self, val: bytes) -> None: ...
    @property
    def repository_id(self) -> bytes: ...
    @repository_id.setter
    def repository_id(self, val: bytes) -> None: ...

class EncryptedKey(PropDict):
    @property
    def version(self) -> int: ...
    @version.setter
    def version(self, val: int) -> None: ...
    @property
    def algorithm(self) -> str: ...
    @algorithm.setter
    def algorithm(self, val: str) -> None: ...
    @property
    def salt(self) -> bytes: ...
    @salt.setter
    def salt(self, val: bytes) -> None: ...
    @property
    def iterations(self) -> int: ...
    @iterations.setter
    def iterations(self, val: int) -> None: ...
    @property
    def data(self) -> bytes: ...
    @data.setter
    def data(self, val: bytes) -> None: ...
    @property
    def hash(self) -> bytes: ...
    @hash.setter
    def hash(self, val: bytes) -> None: ...
    @property
    def label(self) -> str: ...
    @label.setter
    def label(self, val: str) -> None: ...
