from collections import Counter, OrderedDict
from typing import Any, Dict, Iterable, List, Optional, Sequence, Tuple, Union

from django.urls import URLPattern, URLResolver

import coreapi
from rest_framework.fields import Field
from rest_framework.request import Request
from rest_framework.views import APIView

from .generators import BaseSchemaGenerator as BaseSchemaGenerator
from .inspectors import ViewInspector as ViewInspector

def common_path(paths: Iterable[str]) -> str: ...
def is_custom_action(action: str) -> bool: ...
def distribute_links(obj: Any) -> None: ...

INSERT_INTO_COLLISION_FMT: str

class LinkNode(OrderedDict[Any, Any]):
    links: List[Any] = ...
    methods_counter: Counter[Any] = ...
    def __init__(self) -> None: ...
    def get_available_key(self, preferred_key: str) -> str: ...

def insert_into(target: LinkNode, keys: Sequence[str], value: Any) -> None: ...

class SchemaGenerator(BaseSchemaGenerator):
    default_mapping: Dict[str, str] = ...
    coerce_method_names: Optional[Dict[str, str]] = ...
    def __init__(
        self,
        urlconf: Optional[str] = ...,
        title: Optional[str] = ...,
        description: Optional[str] = ...,
        version: Optional[str] = ...,
        patterns: Sequence[Union[URLPattern, URLResolver, Any]] = ...,
        url: Optional[str] = ...,
        endpoints: Optional[Sequence[Tuple[str, str, Any]]] = ...,
    ) -> None: ...
    def get_links(self, request: Optional[Request] = ...) -> Optional[LinkNode]: ...
    def get_schema(self, request: Optional[Request] = ..., public: bool = ...) -> Optional[coreapi.Document]: ...
    def get_keys(self, subpath: Any, method: Any, view: APIView) -> List[str]: ...
    def determine_path_prefix(self, paths: List[str]) -> str: ...

def field_to_schema(field: Field[Any, Any, Any, Any]) -> Any: ...

class AutoSchema(ViewInspector):
    def __init__(self, manual_fields: Optional[List[coreapi.Field]] = ...) -> None: ...
    def get_link(self, path: str, method: str, base_url: str) -> coreapi.Link: ...
    def get_path_fields(self, path: str, method: str) -> List[coreapi.Field]: ...
    def get_serializer_fields(self, path: str, method: str) -> List[coreapi.Field]: ...
    def get_pagination_fields(self, path: str, method: str) -> Dict[str, Any]: ...
    def get_filter_fields(self, path: str, method: str) -> List[Dict[str, Any]]: ...
    def get_manual_fields(self, path: str, method: str) -> List[coreapi.Field]: ...
    @staticmethod
    def update_fields(fields: List[coreapi.Fields], update_with: List[coreapi.Fields]) -> List[coreapi.Fields]: ...
    def get_encoding(self, path: str, method: str) -> str: ...

class ManualSchema(ViewInspector):
    def __init__(self, fields: List[coreapi.Fields], description: str = ..., encoding: Optional[str] = ...) -> None: ...
    def get_link(self, path: str, method: str, base_url: str) -> coreapi.Link: ...

def is_enabled() -> bool: ...
