from typing import Any, Dict, Iterable, List, Mapping
from typing import Sequence as Seq
from typing import Tuple

from _typeshed import Incomplete

from .annotations import annotationType
from .listener import UserListener
from .topicexc import MessageDataSpecError as MessageDataSpecError
from .topicutils import WeakNone, stringize

ArgsDocs = Dict[str, str]
MsgData = Mapping[str, Any]

def verifyArgsDifferent(
    allArgs: Iterable[Any], allParentArgs: Iterable[Any], topicName: str
) -> None: ...
def verifySubset(
    all: Iterable[Any], sub: Iterable[Any], topicName: str, extraMsg: str = ...
) -> None: ...
def topicArgsFromCallable(
    _callable: UserListener, ignoreArgs: Seq[str] = ...
) -> Tuple[ArgsDocs, List[str]]: ...

class ArgSpecGiven:
    SPEC_GIVEN_NONE: int
    SPEC_GIVEN_ALL: int
    reqdArgs: Incomplete
    argsSpecType: Incomplete
    argsDocs: Incomplete
    def __init__(self, argsDocs: ArgsDocs = ..., reqdArgs: Seq[str] = ...) -> None: ...
    def setAll(self, allArgsDocs: ArgsDocs, reqdArgs: Seq[str] = ...) -> None: ...
    def isComplete(self) -> bool: ...
    def getOptional(self) -> List[str]: ...

class SenderMissingReqdMsgDataError(RuntimeError):
    def __init__(
        self, topicName: str, argNames: Seq[str], missing: Seq[str]
    ) -> None: ...

class SenderUnknownMsgDataError(RuntimeError):
    def __init__(self, topicName: str, argNames: Seq[str], extra: Seq[str]) -> None: ...

class ArgsInfo:
    SPEC_MISSING: int
    SPEC_COMPLETE: int
    topicNameTuple: Incomplete
    allOptional: Incomplete
    allDocs: Incomplete
    allRequired: Incomplete
    argsSpecType: Incomplete
    parentAI: Incomplete
    childrenAI: Incomplete
    argsAddedToParent: Incomplete
    def __init__(
        self,
        topicNameTuple: Seq[str],
        specGiven: ArgSpecGiven,
        parentArgsInfo: ArgsInfo,
    ) -> None: ...
    def isComplete(self) -> bool: ...
    def getArgs(self) -> List[str]: ...
    def numArgs(self) -> int: ...
    def getReqdArgs(self) -> List[str]: ...
    def getOptArgs(self) -> List[str]: ...
    def getArgsDocs(self) -> ArgsDocs: ...
    def setArgsDocs(self, docs: ArgsDocs) -> None: ...
    def check(self, msgData: MsgData) -> None: ...
    def filterArgs(self, msgData: MsgData) -> MsgData: ...
    def hasSameArgs(self, *argNames: Seq[str]) -> bool: ...
    def hasParent(self, argsInfo: ArgsInfo) -> bool: ...
    def getCompleteAI(self) -> ArgsInfo: ...
    def updateAllArgsFinal(self, topicDefn: ArgSpecGiven) -> None: ...
