from collections.abc import Callable, Generator
from typing import Any
import re

from django.utils.functional import cached_property

FIND_A_TAG: re.Pattern[str]
FIND_EMBED_TAG: re.Pattern[str]
FIND_ATTRS: re.Pattern[str]

def extract_attrs(attr_string: str) -> dict[str, str]: ...

class TagMatch:
    match: re.Match[str]
    replacement: str | None
    def __init__(self, match: re.Match[str]) -> None: ...
    @cached_property
    def attrs(self) -> dict[str, str]: ...
    @property
    def start(self) -> int: ...
    @property
    def end(self) -> int: ...

class TagRewriter:
    rules: dict[str, Callable[[dict[str, str]], str]]
    bulk_rules: dict[str, Callable[[list[dict[str, str]]], list[str]]]
    reference_extractors: dict[str, Callable[[dict[str, str]], Any]]
    def __init__(
        self,
        rules: dict[str, Callable[[dict[str, str]], str]] | None = None,
        bulk_rules: dict[str, Callable[[list[dict[str, str]]], list[str]]] | None = None,
        reference_extractors: dict[str, Callable[[dict[str, str]], Any]] | None = None,
    ) -> None: ...
    def get_opening_tag_regex(self) -> re.Pattern[str]: ...
    def get_tag_type_from_attrs(self, attrs: dict[str, str]) -> str | None: ...
    def get_tag_replacements(self, tag_type: str | None, attrs_list: list[dict[str, str]]) -> list[str]: ...
    def __call__(self, html: str) -> str: ...
    def extract_tags(self, html: str) -> dict[str, list[TagMatch]]: ...
    def convert_rule_to_bulk_rule(
        self, rule: Callable[[dict[str, str]], str]
    ) -> Callable[[list[dict[str, str]]], list[str]]: ...
    def extract_references(self, html: str) -> Generator[Any]: ...

class EmbedRewriter(TagRewriter):
    def get_opening_tag_regex(self) -> re.Pattern[str]: ...
    def get_tag_type_from_attrs(self, attrs: dict[str, str]) -> str | None: ...
    def get_tag_replacements(self, tag_type: str | None, attrs_list: list[dict[str, str]]) -> list[str]: ...

class LinkRewriter(TagRewriter):
    def get_opening_tag_regex(self) -> re.Pattern[str]: ...
    def get_tag_type_from_attrs(self, attrs: dict[str, str]) -> str | None: ...
    def get_tag_replacements(self, tag_type: str | None, attrs_list: list[dict[str, str]]) -> list[str]: ...

class MultiRuleRewriter:
    rewriters: list[TagRewriter]
    def __init__(self, rewriters: list[TagRewriter]) -> None: ...
    def __call__(self, html: str) -> str: ...
    def extract_references(self, html: str) -> Generator[Any]: ...
