from types import ModuleType
from typing import Any, Callable, Dict, List, Optional, Pattern, Sequence, Tuple, Type, Union, overload

from django.core.checks.messages import CheckMessage
from django.urls import _AnyURL
from django.urls.converters import UUIDConverter
from django.utils.datastructures import MultiValueDict

class ResolverMatch:
    func: Callable = ...
    args: Tuple[Any, ...] = ...
    kwargs: Dict[str, Any] = ...
    url_name: Optional[str] = ...
    app_names: List[str] = ...
    app_name: str = ...
    namespaces: List[str] = ...
    namespace: str = ...
    view_name: str = ...
    route: str = ...
    tried: Optional[Any]
    _func_path: str
    def __init__(
        self,
        func: Callable,
        args: Tuple[Any, ...],
        kwargs: Dict[str, Any],
        url_name: Optional[str] = ...,
        app_names: Optional[List[Optional[str]]] = ...,
        namespaces: Optional[List[Optional[str]]] = ...,
        route: Optional[str] = ...,
        tried: Optional[Any] = ...,
    ) -> None: ...
    def __getitem__(self, index: int) -> Any: ...
    # for tuple unpacking
    def __iter__(self) -> Any: ...

def get_resolver(urlconf: Optional[str] = ...) -> URLResolver: ...
def get_ns_resolver(ns_pattern: str, resolver: URLResolver, converters: Tuple) -> URLResolver: ...

_Pattern = Union[RegexPattern, RoutePattern, LocalePrefixPattern]

class LocaleRegexDescriptor:
    attr: str = ...
    def __init__(self, attr: Any) -> None: ...
    @overload
    def __get__(self, instance: None, cls: Type[_Pattern] = ...) -> LocaleRegexDescriptor: ...
    @overload
    def __get__(self, instance: _Pattern, cls: Type[_Pattern] = ...) -> Pattern[str]: ...

class CheckURLMixin:
    def describe(self) -> str: ...

class RegexPattern(CheckURLMixin):
    regex: LocaleRegexDescriptor = ...
    name: Optional[str] = ...
    converters: Dict[Any, Any] = ...
    def __init__(self, regex: str, name: Optional[str] = ..., is_endpoint: bool = ...) -> None: ...
    def match(self, path: str) -> Optional[Tuple[str, Tuple, Dict[str, str]]]: ...
    def check(self) -> List[CheckMessage]: ...

class RoutePattern(CheckURLMixin):
    regex: LocaleRegexDescriptor = ...
    name: Optional[str] = ...
    converters: Dict[str, UUIDConverter] = ...
    def __init__(self, route: str, name: Optional[str] = ..., is_endpoint: bool = ...) -> None: ...
    def match(self, path: str) -> Optional[Tuple[str, Tuple, Dict[str, Union[int, str]]]]: ...
    def check(self) -> List[CheckMessage]: ...

class LocalePrefixPattern:
    prefix_default_language: bool = ...
    converters: Dict[Any, Any] = ...
    def __init__(self, prefix_default_language: bool = ...) -> None: ...
    @property
    def regex(self) -> Pattern[str]: ...
    @property
    def language_prefix(self) -> str: ...
    def match(self, path: str) -> Optional[Tuple[str, Tuple, Dict[str, Any]]]: ...
    def check(self) -> List[CheckMessage]: ...
    def describe(self) -> str: ...

class URLPattern:
    pattern: _Pattern = ...
    callback: Callable = ...
    default_args: Optional[Dict[str, str]] = ...
    name: Optional[str] = ...
    def __init__(
        self,
        pattern: _Pattern,
        callback: Callable,
        default_args: Optional[Dict[str, str]] = ...,
        name: Optional[str] = ...,
    ) -> None: ...
    def check(self) -> List[CheckMessage]: ...
    def resolve(self, path: str) -> Optional[ResolverMatch]: ...
    @property
    def lookup_str(self) -> str: ...

class URLResolver:
    pattern: _Pattern = ...
    urlconf_name: Union[str, None, Sequence[_AnyURL]] = ...
    callback: None = ...
    default_kwargs: Dict[str, Any] = ...
    namespace: Optional[str] = ...
    app_name: Optional[str] = ...
    _local: Any
    _reverse_dict: MultiValueDict
    def __init__(
        self,
        pattern: _Pattern,
        urlconf_name: Union[str, None, Sequence[_AnyURL]],
        default_kwargs: Optional[Dict[str, Any]] = ...,
        app_name: Optional[str] = ...,
        namespace: Optional[str] = ...,
    ) -> None: ...
    @property
    def reverse_dict(self) -> MultiValueDict: ...
    @property
    def namespace_dict(self) -> Dict[str, Tuple[str, URLResolver]]: ...
    @property
    def app_dict(self) -> Dict[str, List[str]]: ...
    @property
    def urlconf_module(self) -> Union[ModuleType, None, Sequence[_AnyURL]]: ...
    @property
    def url_patterns(self) -> List[_AnyURL]: ...
    def resolve(self, path: str) -> ResolverMatch: ...
    def resolve_error_handler(self, view_type: int) -> Callable: ...
    def reverse(self, lookup_view: str, *args: Any, **kwargs: Any) -> str: ...
    def _is_callback(self, name: str) -> bool: ...
    def _populate(self) -> None: ...
