from typing import (
    Tuple,
    Any,
    Collection,
    Iterable,
    Iterator,
    List,
    Callable,
    Set,
    Union,
    TypeVar,
    overload,
)
from enum import Enum

from pikepdf.models.image import PdfInlineImage

T = TypeVar('T', bound=Object)

def _new_operator(op: str) -> Object: ...
def _Null() -> Any: ...
def _encode(handle: Any) -> Object: ...
def _new_array(arg0: Iterable) -> Object: ...
def _new_boolean(arg0: bool) -> Object: ...
def _new_dictionary(arg0: dict) -> Object: ...
def _new_integer(arg0: int) -> Object: ...
def _new_name(arg0: str) -> Object: ...
@overload
def _new_real(arg0: str) -> Object: ...
@overload
def _new_real(value: float, places: int = ...) -> Object: ...
@overload
def _new_real(*args, **kwargs) -> Any: ...
def _new_stream(arg0: Pdf, arg1: bytes) -> Object: ...
def _new_string(s: Union[str, bytes]) -> Object: ...
def _new_string_utf8(s: str) -> Object: ...
def _test_file_not_found(*args, **kwargs) -> Any: ...
def get_decimal_precision() -> int: ...
def pdf_doc_to_utf8(pdfdoc: bytes) -> str: ...
def qpdf_version() -> str: ...
def set_access_default_mmap(mmap: bool) -> bool: ...
def set_decimal_precision(prec: int) -> int: ...
def unparse(obj: Any) -> bytes: ...
def utf8_to_pdf_doc(utf8: str, unknown: bytes) -> Tuple[bool, bytes]: ...

class AccessMode(Enum):
    default: int = ...
    mmap: int = ...
    mmap_only: int = ...
    stream: int = ...

class Annotation:
    def __init__(self, arg0: Object) -> None: ...
    def get_appearance_stream(self, which: Object, state: str = ...) -> Object: ...
    def get_page_content_for_appearance(
        self,
        name: Object,
        rotate: int,
        required_flags: int = ...,
        forbidden_flags: int = ...,
    ) -> str: ...
    @property
    def appearance_dict(self) -> Object: ...
    @property
    def appearance_state(self) -> str: ...
    @property
    def flags(self) -> int: ...
    @property
    def subtype(self) -> str: ...

class Buffer:
    def __init__(self, *args, **kwargs) -> None: ...

class EncryptionMethod(Enum):
    none: int = ...
    unknown: int = ...
    rc4: int = ...
    aes: int = ...
    aesv3: int = ...

class Object:
    _ipython_key_completions_: Any = ...
    _repr_mimebundle_: Any = ...
    emplace: Any = ...
    write: Any = ...
    def __init__(self, *args, **kwargs) -> None: ...
    def _inline_image_raw_bytes(self) -> bytes: ...
    def _parse_page_contents(self, callbacks: Callable) -> None: ...
    def _parse_page_contents_grouped(
        self, whitelist: str
    ) -> List[Tuple[Collection[Union[Object, 'PdfInlineImage']], Operator]]: ...
    def _parse_stream(self, *args, **kwargs) -> Any: ...
    def _parse_stream_grouped(self, *args, **kwargs) -> Any: ...
    def _write(self, data: bytes, filter: object, decode_parms: object) -> None: ...
    def append(self, pyitem: Object) -> None: ...
    def as_dict(self) -> _ObjectMapping: ...
    def as_list(self) -> _ObjectList: ...
    def extend(self, arg0: Iterable[Object]) -> None: ...
    @overload
    def get(self, key: str, default: object = ...) -> object: ...
    @overload
    def get(key, default=...) -> Any: ...
    @overload
    def get(self, key: Object, default: object = ...) -> object: ...
    @overload
    def get(*args, **kwargs) -> Any: ...
    def get_raw_stream_buffer(self) -> Buffer: ...
    def get_stream_buffer(self, decode_level: StreamDecodeLevel = ...) -> Buffer: ...
    def is_owned_by(self, possible_owner: Pdf) -> bool: ...
    def items(self) -> Iterable[Tuple[str, Object]]: ...
    def keys(self) -> Set[str]: ...
    def page_contents_add(self, contents: Object, prepend: bool = ...) -> None: ...
    def page_contents_coalesce(self) -> None: ...
    @staticmethod
    def parse(stream: bytes, description: str = ...) -> Object: ...
    def read_bytes(self, decode_level: StreamDecodeLevel = ...) -> bytes: ...
    def read_raw_bytes(self) -> bytes: ...
    def same_owner_as(self, other: Object) -> bool: ...
    def to_json(self, dereference: bool = ...) -> bytes: ...
    def unparse(self, resolved: bool = ...) -> bytes: ...
    def wrap_in_array(self) -> Object: ...
    def __bytes__(self) -> bytes: ...
    @overload
    def __contains__(self, arg0: Object) -> bool: ...
    @overload
    def __contains__(self, arg0: str) -> bool: ...
    @overload
    def __contains__(*args, **kwargs) -> Any: ...
    def __copy__(self) -> Object: ...
    def __delattr__(self, arg0: str) -> None: ...
    @overload
    def __delitem__(self, arg0: str) -> None: ...
    @overload
    def __delitem__(self, arg0: Object) -> None: ...
    @overload
    def __delitem__(self, arg0: int) -> None: ...
    @overload
    def __delitem__(*args, **kwargs) -> Any: ...
    def __dir__(self) -> list: ...
    def __eq__(self, other: Any) -> bool: ...
    def __getattr__(self, arg0: str) -> Object: ...
    @overload
    def __getitem__(self, arg0: str) -> Object: ...
    @overload
    def __getitem__(self, arg0: Object) -> Object: ...
    @overload
    def __getitem__(self, arg0: int) -> Object: ...
    @overload
    def __getitem__(*args, **kwargs) -> Any: ...
    def __hash__(self) -> int: ...
    def __iter__(self) -> Iterable[Object]: ...
    def __len__(self) -> int: ...
    def __setattr__(self, arg0: str, arg1: object) -> None: ...
    @overload
    def __setitem__(self, arg0: str, arg1: Object) -> None: ...
    @overload
    def __setitem__(self, arg0: Object, arg1: Object) -> None: ...
    @overload
    def __setitem__(self, arg0: str, arg1: object) -> None: ...
    @overload
    def __setitem__(self, arg0: Object, arg1: object) -> None: ...
    @overload
    def __setitem__(self, arg0: int, arg1: Object) -> None: ...
    @overload
    def __setitem__(self, arg0: int, arg1: object) -> None: ...
    @overload
    def __setitem__(*args, **kwargs) -> Any: ...
    @property
    def _objgen(self) -> Tuple[int, int]: ...
    @property
    def _type_code(self) -> ObjectType: ...
    @property
    def _type_name(self) -> str: ...
    @property
    def images(self) -> _ObjectMapping: ...
    @property
    def is_indirect(self) -> bool: ...
    @property
    def is_rectangle(self) -> bool: ...
    @property
    def objgen(self) -> Tuple[int, int]: ...
    @property
    def stream_dict(self) -> Object: ...
    @stream_dict.setter
    def stream_dict(self, val: Object) -> None: ...

class Operator(Object): ...

class ObjectStreamMode(Enum):
    disable: Any = ...
    generate: Any = ...
    preserve: Any = ...

class ObjectType(Enum):
    array: Any = ...
    boolean: Any = ...
    dictionary: Any = ...
    inlineimage: Any = ...
    integer: Any = ...
    name: Any = ...
    null: Any = ...
    operator: Any = ...
    real: Any = ...
    reserved: Any = ...
    stream: Any = ...
    string: Any = ...
    uninitialized: Any = ...

class Page:
    _repr_mimebundle_: Any = ...
    def __init__(self, arg0: Object) -> None: ...
    def _get_cropbox(self, arg0: bool) -> Object: ...
    def _get_mediabox(self, arg0: bool) -> Object: ...
    def _get_trimbox(self, arg0: bool) -> Object: ...
    def add_content_token_filter(self, tf) -> None: ...
    def as_form_xobject(self, handle_transformations: bool = ...) -> Object: ...
    def contents_coalesce(self) -> None: ...
    def externalize_inline_images(self, min_size: int = ...) -> None: ...
    def get_filtered_contents(self, tf: TokenFilter) -> bytes: ...
    def parse_contents(self, arg0: StreamParser) -> None: ...
    def remove_unreferenced_resources(self) -> None: ...
    def rotate(self, angle: int, relative: bool) -> None: ...
    @property
    def _images(self) -> _ObjectMapping: ...
    @property
    def cropbox(self) -> Any: ...
    @cropbox.setter
    def cropbox(self, val: Any) -> None: ...
    @property
    def mediabox(self) -> Any: ...
    @mediabox.setter
    def mediabox(self, val: Any) -> None: ...
    @property
    def obj(self) -> Object: ...
    @property
    def trimbox(self) -> Any: ...
    @trimbox.setter
    def trimbox(self, val: Any) -> None: ...

class PageList:
    def __init__(self, *args, **kwargs) -> None: ...
    def append(self, page: object) -> None: ...
    @overload
    def extend(self, other: PageList) -> None: ...
    @overload
    def extend(self, iterable: Iterable[Object]) -> None: ...
    def insert(self, index: int, obj: object) -> None: ...
    def p(self, pnum: int) -> Object: ...
    def remove(self, **kwargs) -> None: ...
    def reverse(self) -> None: ...
    @overload
    def __delitem__(self, arg0: int) -> None: ...
    @overload
    def __delitem__(self, arg0: slice) -> None: ...
    @overload
    def __delitem__(*args, **kwargs) -> Any: ...
    @overload
    def __getitem__(self, arg0: int) -> Object: ...
    @overload
    def __getitem__(self, arg0: slice) -> list: ...
    @overload
    def __getitem__(*args, **kwargs) -> Any: ...
    def __iter__(self) -> PageList: ...
    def __len__(self) -> int: ...
    def __next__(self) -> Object: ...
    @overload
    def __setitem__(self, arg0: int, arg1: Object) -> None: ...
    @overload
    def __setitem__(self, arg0: slice, arg1: Iterable[Object]) -> None: ...
    @overload
    def __setitem__(*args, **kwargs) -> Any: ...

class PasswordError(Exception): ...
class ForeignObjectError(Exception): ...

class Pdf:
    _attach: Any = ...
    _repr_mimebundle_: Any = ...
    add_blank_page: Any = ...
    check: Any = ...
    close: Any = ...
    make_stream: Any = ...
    open: Any = ...
    open_metadata: Any = ...
    open_outline: Any = ...
    save: Any = ...
    __enter__: Any = ...
    __exit__: Any = ...
    def __init__(self, *args, **kwargs) -> None: ...
    def _add_page(self, page: Object, first: bool = ...) -> None: ...
    def _add_page_at(self, arg0: Object, arg1: bool, arg2: Object) -> None: ...
    def _decode_all_streams_and_discard(self) -> None: ...
    def _get_object_id(self, arg0: int, arg1: int) -> Object: ...
    def _open(self, *args, **kwargs) -> Any: ...
    def _process(self, arg0: str, arg1: bytes) -> None: ...
    def _remove_page(self, arg0: Object) -> None: ...
    def _replace_object(self, arg0: Tuple[int, int], arg1: Object) -> None: ...
    def _save(
        self,
        filename: object,
        static_id: bool = ...,
        preserve_pdfa: bool = ...,
        min_version: object = ...,
        force_version: object = ...,
        fix_metadata_version: bool = ...,
        compress_streams: bool = ...,
        stream_decode_level: object = ...,
        object_stream_mode: ObjectStreamMode = ...,
        normalize_content: bool = ...,
        linearize: bool = ...,
        qdf: bool = ...,
        progress: object = ...,
        encryption: object = ...,
        samefile_check: bool = ...,
    ) -> None: ...
    def _swap_objects(self, arg0: Tuple[int, int], arg1: Tuple[int, int]) -> None: ...
    def check_linearization(self, stream: object = ...) -> bool: ...
    def copy_foreign(self, h: Object) -> Object: ...
    @overload
    def get_object(self, objgen: Tuple[int, int]) -> Object: ...
    @overload
    def get_object(self, objid: int, gen: int) -> Object: ...
    @overload
    def get_object(*args, **kwargs) -> Any: ...
    def get_warnings(self) -> list: ...
    @overload
    def make_indirect(self, h: T) -> T: ...
    @overload
    def make_indirect(self, obj: object) -> Object: ...
    def new(self, *args, **kwargs) -> Any: ...
    def remove_unreferenced_resources(self) -> None: ...
    def show_xref_table(self) -> None: ...
    @property
    def Root(self) -> Object: ...
    @property
    def _allow_accessibility(self) -> bool: ...
    @property
    def _allow_extract(self) -> bool: ...
    @property
    def _allow_modify_all(self) -> bool: ...
    @property
    def _allow_modify_annotation(self) -> bool: ...
    @property
    def _allow_modify_assembly(self) -> bool: ...
    @property
    def _allow_modify_form(self) -> bool: ...
    @property
    def _allow_modify_other(self) -> bool: ...
    @property
    def _allow_print_highres(self) -> bool: ...
    @property
    def _allow_print_lowres(self) -> bool: ...
    @property
    def _encryption_data(self) -> dict: ...
    @property
    def _pages(self) -> Any: ...
    @property
    def allow(self) -> Any: ...
    @property
    def docinfo(self) -> Object: ...
    @docinfo.setter
    def docinfo(self, val: Object) -> None: ...
    @property
    def encryption(self) -> Any: ...
    @property
    def extension_level(self) -> int: ...
    @property
    def filename(self) -> str: ...
    @property
    def is_encrypted(self) -> bool: ...
    @property
    def is_linearized(self) -> bool: ...
    @property
    def objects(self) -> Any: ...
    @property
    def pages(self) -> PageList: ...
    @property
    def pdf_version(self) -> str: ...
    @property
    def root(self) -> Object: ...
    @property
    def trailer(self) -> Object: ...

class PdfError(Exception): ...

class StreamDecodeLevel(Enum):
    all: Any = ...
    generalized: Any = ...
    none: Any = ...
    specialized: Any = ...

class StreamParser:
    def __init__(self) -> None: ...
    def handle_eof(self) -> None: ...
    def handle_object(self, arg0: Object) -> None: ...

class Token:
    def __init__(self, arg0: TokenType, arg1: bytes) -> None: ...
    def __eq__(self, other: Any) -> bool: ...
    @property
    def error_msg(self) -> str: ...
    @property
    def raw_value(self) -> bytes: ...
    @property
    def type_(self) -> TokenType: ...
    @property
    def value(self) -> str: ...

class TokenFilter(_QPDFTokenFilter):
    def __init__(self) -> None: ...
    def handle_token(self, token: Token = ...) -> object: ...

class TokenType(Enum):
    array_close: Any = ...
    array_open: Any = ...
    bad: Any = ...
    bool: Any = ...
    brace_close: Any = ...
    brace_open: Any = ...
    comment: Any = ...
    dict_close: Any = ...
    dict_open: Any = ...
    eof: Any = ...
    inline_image: Any = ...
    integer: Any = ...
    name: Any = ...
    null: Any = ...
    real: Any = ...
    space: Any = ...
    string: Any = ...
    word: Any = ...

class _ObjectList:
    @overload
    def __init__(self) -> None: ...
    @overload
    def __init__(self, arg0: _ObjectList) -> None: ...
    @overload
    def __init__(self, arg0: Iterable) -> None: ...
    @overload
    def __init__(*args, **kwargs) -> None: ...
    def append(self, x: Object) -> None: ...
    def clear(self) -> None: ...
    def count(self, x: Object) -> int: ...
    @overload
    def extend(self, L: _ObjectList) -> None: ...
    @overload
    def extend(self, L: Iterable[Object]) -> None: ...
    def insert(self, i: int, x: Object) -> None: ...
    @overload
    def pop(self) -> Object: ...
    @overload
    def pop(self, i: int) -> Object: ...
    @overload
    def pop(*args, **kwargs) -> Any: ...
    def remove(self, x: Object) -> None: ...
    def __bool__(self) -> bool: ...
    def __contains__(self, x: Object) -> bool: ...
    @overload
    def __delitem__(self, arg0: int) -> None: ...
    @overload
    def __delitem__(self, arg0: slice) -> None: ...
    @overload
    def __delitem__(*args, **kwargs) -> Any: ...
    def __eq__(self, other: Any) -> bool: ...
    @overload
    def __getitem__(self, s: slice) -> _ObjectList: ...
    @overload
    def __getitem__(self, arg0: int) -> Object: ...
    @overload
    def __getitem__(*args, **kwargs) -> Any: ...
    def __iter__(self) -> Iterator[Object]: ...
    def __len__(self) -> int: ...
    def __ne__(self, other: Any) -> bool: ...
    @overload
    def __setitem__(self, arg0: int, arg1: Object) -> None: ...
    @overload
    def __setitem__(self, arg0: slice, arg1: _ObjectList) -> None: ...
    @overload
    def __setitem__(*args, **kwargs) -> Any: ...

class _ObjectMapping:
    get: Any = ...
    keys: Any = ...
    values: Any = ...
    __contains__: Any = ...
    def __init__(self) -> None: ...
    def items(self) -> Iterator: ...
    def __bool__(self) -> bool: ...
    def __delitem__(self, arg0: str) -> None: ...
    def __getitem__(self, arg0: str) -> Object: ...
    def __iter__(self) -> Iterator: ...
    def __len__(self) -> int: ...
    def __setitem__(self, arg0: str, arg1: Object) -> None: ...

class _QPDFTokenFilter:
    def __init__(self, *args, **kwargs) -> None: ...
