from _typeshed import Incomplete
from typing import Any, Final, Literal, Protocol, TypeVar, overload, type_check_only

import _win32typing
from win32.lib.pywintypes import IIDType
from win32com.client import build

_T_co = TypeVar("_T_co", covariant=True)
_T = TypeVar("_T")

@type_check_only
class _DispatchCreateClass(Protocol[_T_co]):
    @staticmethod
    def __call__(
        IDispatch: str | PyIDispatchType | IIDType | PyIUnknownType,
        olerepr: build.DispatchItem | build.LazyDispatchItem,
        userName: str | None = None,
        lazydata=None,
    ) -> _T_co: ...

debugging: int
debugging_attr: int
LCID: Final = 0x0
ERRORS_BAD_CONTEXT: Final[list[int]]
ALL_INVOKE_TYPES: Final[list[int]]

def debug_print(*args: object) -> None: ...
def debug_attr_print(*args: object) -> None: ...

PyIDispatchType = _win32typing.PyIDispatch
PyIUnknownType = _win32typing.PyIUnknown

@overload
def Dispatch(
    IDispatch: str | PyIDispatchType | IIDType | PyIUnknownType,
    userName: str | None,
    createClass: _DispatchCreateClass[_T],
    typeinfo: _win32typing.PyITypeInfo | None = None,
    clsctx: int = ...,
) -> _T: ...
@overload
def Dispatch(
    IDispatch: str | PyIDispatchType | IIDType | PyIUnknownType,
    userName: str | None = None,
    createClass: None = None,
    typeinfo: _win32typing.PyITypeInfo | None = None,
    clsctx: int = ...,
) -> CDispatch: ...

def MakeOleRepr(IDispatch, typeinfo, typecomp) -> build.DispatchItem | build.LazyDispatchItem: ...
def DumbDispatch(IDispatch, userName=None, createClass=None, clsctx=...): ...

class CDispatch:
    def __init__(self, IDispatch, olerepr, userName=None, lazydata=None) -> None: ...
    def __call__(self, *args): ...
    def __bool__(self) -> bool: ...
    def __dir__(self) -> list[str]: ...
    def __eq__(self, other) -> bool: ...
    def __ne__(self, other) -> bool: ...
    def __int__(self) -> int: ...
    def __len__(self) -> int: ...
    def __getitem__(self, index): ...
    def __setitem__(self, index, *args) -> None: ...
    def __LazyMap__(self, attr) -> Literal[0, 1] | None: ...
    def __AttrToID__(self, attr): ...
    ob: Incomplete
    # CDispatch objects are dynamically generated and too complex to type
    def __getattr__(self, attr: str) -> Any: ...
    def __setattr__(self, attr: str, value: Any) -> None: ...
