from _typeshed import Incomplete
from collections import deque
from collections.abc import Callable, Iterator
from typing import TypedDict, overload, type_check_only

from ._inputstream import HTMLBinaryInputStream, HTMLUnicodeInputStream, _BinaryInputStream, _UnicodeInputStream
from ._trie import Trie

@type_check_only
class _DataVars(TypedDict, total=False):
    data: str | None
    charAsInt: int

@type_check_only
class _Token(TypedDict, total=False):
    type: int
    data: str | list[str]
    datavars: _DataVars
    name: str
    selfClosing: bool
    selfClosingAcknowledged: bool
    publicId: str | None
    systemId: str | None
    correct: bool

entitiesTrie: Trie
attributeMap = dict

class HTMLTokenizer:
    # TODO: Use Protocol to allow subclasses to set `stream` that do not inherit from HTMLUnicodeInputStream
    stream: HTMLUnicodeInputStream | HTMLBinaryInputStream
    parser: Incomplete
    escapeFlag: bool
    lastFourChars: list[Incomplete]
    state: Callable[[], bool]
    escape: bool
    currentToken: _Token | None

    @overload
    def __init__(self, stream: _UnicodeInputStream, parser=None) -> None: ...
    @overload
    def __init__(
        self,
        stream: _BinaryInputStream,
        parser=None,
        *,
        override_encoding: str | bytes | None = None,
        transport_encoding: str | bytes | None = None,
        same_origin_parent_encoding: str | bytes | None = None,
        likely_encoding: str | bytes | None = None,
        default_encoding: str = "windows-1252",
        useChardet: bool = True,
    ) -> None: ...

    tokenQueue: deque[_Token]
    def __iter__(self) -> Iterator[_Token]: ...
    def consumeNumberEntity(self, isHex: bool | None) -> str: ...
    def consumeEntity(self, allowedChar: str | None = None, fromAttribute: bool = False) -> None: ...
    def processEntityInAttribute(self, allowedChar: str | None) -> None: ...
    def emitCurrentToken(self) -> None: ...
    def dataState(self) -> bool: ...
    def entityDataState(self) -> bool: ...
    def rcdataState(self) -> bool: ...
    def characterReferenceInRcdata(self) -> bool: ...
    def rawtextState(self) -> bool: ...
    def scriptDataState(self) -> bool: ...
    def plaintextState(self) -> bool: ...
    def tagOpenState(self) -> bool: ...
    def closeTagOpenState(self) -> bool: ...
    def tagNameState(self) -> bool: ...
    temporaryBuffer: str
    def rcdataLessThanSignState(self) -> bool: ...
    def rcdataEndTagOpenState(self) -> bool: ...
    def rcdataEndTagNameState(self) -> bool: ...
    def rawtextLessThanSignState(self) -> bool: ...
    def rawtextEndTagOpenState(self) -> bool: ...
    def rawtextEndTagNameState(self) -> bool: ...
    def scriptDataLessThanSignState(self) -> bool: ...
    def scriptDataEndTagOpenState(self) -> bool: ...
    def scriptDataEndTagNameState(self) -> bool: ...
    def scriptDataEscapeStartState(self) -> bool: ...
    def scriptDataEscapeStartDashState(self) -> bool: ...
    def scriptDataEscapedState(self) -> bool: ...
    def scriptDataEscapedDashState(self) -> bool: ...
    def scriptDataEscapedDashDashState(self) -> bool: ...
    def scriptDataEscapedLessThanSignState(self) -> bool: ...
    def scriptDataEscapedEndTagOpenState(self) -> bool: ...
    def scriptDataEscapedEndTagNameState(self) -> bool: ...
    def scriptDataDoubleEscapeStartState(self) -> bool: ...
    def scriptDataDoubleEscapedState(self) -> bool: ...
    def scriptDataDoubleEscapedDashState(self) -> bool: ...
    def scriptDataDoubleEscapedDashDashState(self) -> bool: ...
    def scriptDataDoubleEscapedLessThanSignState(self) -> bool: ...
    def scriptDataDoubleEscapeEndState(self) -> bool: ...
    def beforeAttributeNameState(self) -> bool: ...
    def attributeNameState(self) -> bool: ...
    def afterAttributeNameState(self) -> bool: ...
    def beforeAttributeValueState(self) -> bool: ...
    def attributeValueDoubleQuotedState(self) -> bool: ...
    def attributeValueSingleQuotedState(self) -> bool: ...
    def attributeValueUnQuotedState(self) -> bool: ...
    def afterAttributeValueState(self) -> bool: ...
    def selfClosingStartTagState(self) -> bool: ...
    def bogusCommentState(self) -> bool: ...
    def markupDeclarationOpenState(self) -> bool: ...
    def commentStartState(self) -> bool: ...
    def commentStartDashState(self) -> bool: ...
    def commentState(self) -> bool: ...
    def commentEndDashState(self) -> bool: ...
    def commentEndState(self) -> bool: ...
    def commentEndBangState(self) -> bool: ...
    def doctypeState(self) -> bool: ...
    def beforeDoctypeNameState(self) -> bool: ...
    def doctypeNameState(self) -> bool: ...
    def afterDoctypeNameState(self) -> bool: ...
    def afterDoctypePublicKeywordState(self) -> bool: ...
    def beforeDoctypePublicIdentifierState(self) -> bool: ...
    def doctypePublicIdentifierDoubleQuotedState(self) -> bool: ...
    def doctypePublicIdentifierSingleQuotedState(self) -> bool: ...
    def afterDoctypePublicIdentifierState(self) -> bool: ...
    def betweenDoctypePublicAndSystemIdentifiersState(self) -> bool: ...
    def afterDoctypeSystemKeywordState(self) -> bool: ...
    def beforeDoctypeSystemIdentifierState(self) -> bool: ...
    def doctypeSystemIdentifierDoubleQuotedState(self) -> bool: ...
    def doctypeSystemIdentifierSingleQuotedState(self) -> bool: ...
    def afterDoctypeSystemIdentifierState(self) -> bool: ...
    def bogusDoctypeState(self) -> bool: ...
    def cdataSectionState(self) -> bool: ...
