from typing import Any, Callable, Optional, Sequence, Type

from rest_framework.authentication import BaseAuthentication
from rest_framework.parsers import BaseParser
from rest_framework.permissions import BasePermission
from rest_framework.renderers import BaseRenderer
from rest_framework.schemas.inspectors import ViewInspector
from rest_framework.throttling import BaseThrottle

_ViewCallable = Callable
_ViewDecorator = Callable[[Callable], _ViewCallable]

def api_view(http_method_names: Optional[Sequence[str]] = ...) -> _ViewDecorator: ...
def renderer_classes(renderer_classes: Sequence[Type[BaseRenderer]]) -> _ViewDecorator: ...
def parser_classes(parser_classes: Sequence[Type[BaseParser]]) -> _ViewDecorator: ...
def authentication_classes(authentication_classes: Sequence[Type[BaseAuthentication]]) -> _ViewDecorator: ...
def throttle_classes(throttle_classes: Sequence[Type[BaseThrottle]]) -> _ViewDecorator: ...
def permission_classes(permission_classes: Sequence[Type[BasePermission]]) -> _ViewDecorator: ...
def schema(view_inspector: Type[ViewInspector]) -> _ViewDecorator: ...
def action(
    methods: Optional[Sequence[str]] = ...,
    detail: Optional[bool] = ...,
    url_path: Optional[str] = ...,
    url_name: Optional[str] = ...,
    **kwargs: Any
) -> _ViewDecorator: ...

class MethodMapper(dict):
    def __init__(self, action: Callable, methods: Sequence[str]) -> None: ...
    def _map(self, method: str, func: Callable) -> Callable: ...
    def get(self, func: Callable) -> Callable: ...  # type: ignore
    def post(self, func: Callable) -> Callable: ...
    def put(self, func: Callable) -> Callable: ...
    def patch(self, func: Callable) -> Callable: ...
    def delete(self, func: Callable) -> Callable: ...
    def head(self, func: Callable) -> Callable: ...
    def options(self, func: Callable) -> Callable: ...
    def trace(self, func: Callable) -> Callable: ...

def detail_route(methods: Optional[Sequence[str]] = ..., **kwargs: Any) -> _ViewDecorator: ...
def list_route(methods: Optional[Sequence[str]] = ..., **kwargs: Any) -> _ViewDecorator: ...
