from collections.abc import Callable, Collection, Iterable, Mapping, Sequence, Sized
from typing import Any, TypeVar, overload

from django.template.base import FilterExpression, Parser
from django.template.context import Context
from django.utils.safestring import SafeString

from .base import Node, NodeList, Template

class InvalidTemplateLibrary(Exception): ...

_C = TypeVar("_C", bound=Callable[..., Any])

class Library:
    filters: dict[str, Callable[..., Any]]
    tags: dict[str, Callable[..., Any]]
    def __init__(self) -> None: ...
    @overload
    def tag(self, name: _C) -> _C: ...
    @overload
    def tag(self, name: str, compile_function: _C) -> _C: ...
    @overload
    def tag(self, name: str | None = None, compile_function: None = None) -> Callable[[_C], _C]: ...
    def tag_function(self, func: _C) -> _C: ...
    @overload
    def filter(self, name: _C, filter_func: None = None, **flags: Any) -> _C: ...
    @overload
    def filter(self, name: str | None, filter_func: _C, **flags: Any) -> _C: ...
    @overload
    def filter(self, name: str | None = None, filter_func: None = None, **flags: Any) -> Callable[[_C], _C]: ...
    def filter_function(self, func: _C, **flags: Any) -> _C: ...
    @overload
    def simple_tag(self, func: _C, takes_context: bool | None = None, name: str | None = None) -> _C: ...
    @overload
    def simple_tag(
        self, func: None = None, takes_context: bool | None = None, name: str | None = None
    ) -> Callable[[_C], _C]: ...
    @overload
    def simple_block_tag(
        self,
        func: _C,
        takes_context: bool | None = None,
        name: str | None = None,
        end_name: str | None = None,
    ) -> _C: ...
    @overload
    def simple_block_tag(
        self,
        func: None = None,
        takes_context: bool | None = None,
        name: str | None = None,
        end_name: str | None = None,
    ) -> Callable[[_C], _C]: ...
    @overload
    def inclusion_tag(
        self,
        filename: Template | str,
        func: _C,
        takes_context: bool | None = None,
        name: str | None = None,
    ) -> _C: ...
    @overload
    def inclusion_tag(
        self,
        filename: Template | str,
        func: None = None,
        takes_context: bool | None = None,
        name: str | None = None,
    ) -> Callable[[_C], _C]: ...

class TagHelperNode(Node):
    func: Any
    takes_context: Any
    args: Any
    kwargs: Any
    def __init__(
        self,
        func: Callable[..., Any],
        takes_context: bool | None,
        args: list[FilterExpression],
        kwargs: dict[str, FilterExpression],
    ) -> None: ...
    def get_resolved_arguments(self, context: Context) -> tuple[list[int], dict[str, SafeString | int]]: ...

class SimpleNode(TagHelperNode):
    args: list[FilterExpression]
    func: Callable[..., Any]
    kwargs: dict[str, FilterExpression]
    takes_context: bool | None
    target_var: str | None
    def __init__(
        self,
        func: Callable[..., Any],
        takes_context: bool | None,
        args: list[FilterExpression],
        kwargs: dict[str, FilterExpression],
        target_var: str | None,
    ) -> None: ...

class SimpleBlockNode(SimpleNode):
    nodelist: NodeList

    def __init__(
        self,
        nodelist: NodeList,
        *args: Any,
        **kwargs: Any,
    ) -> None: ...

class InclusionNode(TagHelperNode):
    args: list[FilterExpression]
    func: Callable[..., Any]
    kwargs: dict[str, FilterExpression]
    takes_context: bool | None
    filename: Template | str
    def __init__(
        self,
        func: Callable[..., Any],
        takes_context: bool | None,
        args: list[FilterExpression],
        kwargs: dict[str, FilterExpression],
        filename: Template | str | None,
    ) -> None: ...

def parse_bits(
    parser: Parser,
    bits: Iterable[str],
    params: Sequence[str],
    varargs: str | None,
    varkw: str | None,
    defaults: Sized | None,
    kwonly: Collection[str],
    kwonly_defaults: Mapping[str, int] | None,
    takes_context: bool | None,
    name: str,
) -> tuple[list[FilterExpression], dict[str, FilterExpression]]: ...
def import_library(name: str) -> Library: ...
