"""Python wrapper for Expat parser."""

import sys
from _typeshed import ReadableBuffer, SupportsRead
from collections.abc import Callable
from pyexpat import errors as errors, model as model
from typing import Any, Final, final
from typing_extensions import CapsuleType, TypeAlias
from xml.parsers.expat import ExpatError as ExpatError

EXPAT_VERSION: Final[str]  # undocumented
version_info: tuple[int, int, int]  # undocumented
native_encoding: str  # undocumented
features: list[tuple[str, int]]  # undocumented

error = ExpatError
XML_PARAM_ENTITY_PARSING_NEVER: Final = 0
XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE: Final = 1
XML_PARAM_ENTITY_PARSING_ALWAYS: Final = 2

_Model: TypeAlias = tuple[int, int, str | None, tuple[Any, ...]]

@final
class XMLParserType:
    """XML parser"""

    def Parse(self, data: str | ReadableBuffer, isfinal: bool = False, /) -> int:
        """Parse XML data.

        'isfinal' should be true at end of input.
        """

    def ParseFile(self, file: SupportsRead[bytes], /) -> int:
        """Parse XML data from file-like object."""

    def SetBase(self, base: str, /) -> None:
        """Set the base URL for the parser."""

    def GetBase(self) -> str | None:
        """Return base URL string for the parser."""

    def GetInputContext(self) -> bytes | None:
        """Return the untranslated text of the input that caused the current event.

        If the event was generated by a large amount of text (such as a start tag
        for an element with many attributes), not all of the text may be available.
        """

    def ExternalEntityParserCreate(self, context: str | None, encoding: str = ..., /) -> XMLParserType:
        """Create a parser for parsing an external entity based on the information passed to the ExternalEntityRefHandler."""

    def SetParamEntityParsing(self, flag: int, /) -> int:
        """Controls parsing of parameter entities (including the external DTD subset).

        Possible flag values are XML_PARAM_ENTITY_PARSING_NEVER,
        XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE and
        XML_PARAM_ENTITY_PARSING_ALWAYS. Returns true if setting the flag
        was successful.
        """

    def UseForeignDTD(self, flag: bool = True, /) -> None:
        """Allows the application to provide an artificial external subset if one is not specified as part of the document instance.

        This readily allows the use of a 'default' document type controlled by the
        application, while still getting the advantage of providing document type
        information to the parser. 'flag' defaults to True if not provided.
        """

    def GetReparseDeferralEnabled(self) -> bool:
        """Retrieve reparse deferral enabled status; always returns false with Expat <2.6.0."""

    def SetReparseDeferralEnabled(self, enabled: bool, /) -> None:
        """Enable/Disable reparse deferral; enabled by default with Expat >=2.6.0."""
    if sys.version_info >= (3, 10):
        # Added in Python 3.10.20, 3.11.15, 3.12.3, 3.13.10, 3.14.1
        def SetAllocTrackerActivationThreshold(self, threshold: int, /) -> None:
            """Sets the number of allocated bytes of dynamic memory needed to activate protection against disproportionate use of RAM.

            By default, parser objects have an allocation activation threshold of 64 MiB.
            """

        def SetAllocTrackerMaximumAmplification(self, max_factor: float, /) -> None:
            """Sets the maximum amplification factor between direct input and bytes of dynamic memory allocated.

            The amplification factor is calculated as "allocated / direct" while parsing,
            where "direct" is the number of bytes read from the primary document in parsing
            and "allocated" is the number of bytes of dynamic memory allocated in the parser
            hierarchy.

            The 'max_factor' value must be a non-NaN floating point value greater than
            or equal to 1.0. Amplification factors greater than 100.0 can be observed
            near the start of parsing even with benign files in practice. In particular,
            the activation threshold should be carefully chosen to avoid false positives.

            By default, parser objects have a maximum amplification factor of 100.0.
            """

    @property
    def intern(self) -> dict[str, str]: ...
    buffer_size: int
    buffer_text: bool
    buffer_used: int
    namespace_prefixes: bool  # undocumented
    ordered_attributes: bool
    specified_attributes: bool
    ErrorByteIndex: int
    ErrorCode: int
    ErrorColumnNumber: int
    ErrorLineNumber: int
    CurrentByteIndex: int
    CurrentColumnNumber: int
    CurrentLineNumber: int
    XmlDeclHandler: Callable[[str, str | None, int], Any] | None
    StartDoctypeDeclHandler: Callable[[str, str | None, str | None, bool], Any] | None
    EndDoctypeDeclHandler: Callable[[], Any] | None
    ElementDeclHandler: Callable[[str, _Model], Any] | None
    AttlistDeclHandler: Callable[[str, str, str, str | None, bool], Any] | None
    StartElementHandler: (
        Callable[[str, dict[str, str]], Any]
        | Callable[[str, list[str]], Any]
        | Callable[[str, dict[str, str], list[str]], Any]
        | None
    )
    EndElementHandler: Callable[[str], Any] | None
    ProcessingInstructionHandler: Callable[[str, str], Any] | None
    CharacterDataHandler: Callable[[str], Any] | None
    UnparsedEntityDeclHandler: Callable[[str, str | None, str, str | None, str], Any] | None
    EntityDeclHandler: Callable[[str, bool, str | None, str | None, str, str | None, str | None], Any] | None
    NotationDeclHandler: Callable[[str, str | None, str, str | None], Any] | None
    StartNamespaceDeclHandler: Callable[[str, str], Any] | None
    EndNamespaceDeclHandler: Callable[[str], Any] | None
    CommentHandler: Callable[[str], Any] | None
    StartCdataSectionHandler: Callable[[], Any] | None
    EndCdataSectionHandler: Callable[[], Any] | None
    DefaultHandler: Callable[[str], Any] | None
    DefaultHandlerExpand: Callable[[str], Any] | None
    NotStandaloneHandler: Callable[[], int] | None
    ExternalEntityRefHandler: Callable[[str, str | None, str | None, str | None], int] | None
    SkippedEntityHandler: Callable[[str, bool], Any] | None

def ErrorString(code: int, /) -> str:
    """Returns string error for given number."""

# intern is undocumented
def ParserCreate(
    encoding: str | None = None, namespace_separator: str | None = None, intern: dict[str, Any] | None = None
) -> XMLParserType:
    """Return a new XML parser object."""

expat_CAPI: CapsuleType
