import asyncio
from .const import CONF_SOURCE_ID as CONF_SOURCE_ID, DLNA_BROWSE_FILTER as DLNA_BROWSE_FILTER, DLNA_PATH_FILTER as DLNA_PATH_FILTER, DLNA_RESOLVE_FILTER as DLNA_RESOLVE_FILTER, DLNA_SORT_CRITERIA as DLNA_SORT_CRITERIA, DOMAIN as DOMAIN, LOGGER as LOGGER, MEDIA_CLASS_MAP as MEDIA_CLASS_MAP, PATH_OBJECT_ID_FLAG as PATH_OBJECT_ID_FLAG, PATH_SEARCH_FLAG as PATH_SEARCH_FLAG, PATH_SEP as PATH_SEP, ROOT_OBJECT_ID as ROOT_OBJECT_ID, STREAMABLE_PROTOCOLS as STREAMABLE_PROTOCOLS
from _typeshed import Incomplete
from async_upnp_client.client import UpnpRequester as UpnpRequester
from async_upnp_client.client_factory import UpnpFactory
from async_upnp_client.profiles.dlna import DmsDevice
from collections.abc import Callable as Callable, Coroutine
from dataclasses import dataclass
from didl_lite import didl_lite
from enum import StrEnum
from homeassistant.backports.functools import cached_property as cached_property
from homeassistant.components import ssdp as ssdp
from homeassistant.components.media_player import BrowseError as BrowseError, MediaClass as MediaClass
from homeassistant.components.media_source.error import Unresolvable as Unresolvable
from homeassistant.components.media_source.models import BrowseMediaSource as BrowseMediaSource, PlayMedia as PlayMedia
from homeassistant.config_entries import ConfigEntry as ConfigEntry
from homeassistant.const import CONF_DEVICE_ID as CONF_DEVICE_ID, CONF_URL as CONF_URL
from homeassistant.core import HomeAssistant as HomeAssistant, callback as callback
from homeassistant.helpers import aiohttp_client as aiohttp_client
from typing import Any, TypeVar

_DlnaDmsDeviceMethod = TypeVar('_DlnaDmsDeviceMethod', bound='DmsDeviceSource')
_R = TypeVar('_R')

class DlnaDmsData:
    hass: HomeAssistant
    requester: UpnpRequester
    upnp_factory: UpnpFactory
    devices: dict[str, DmsDeviceSource]
    sources: dict[str, DmsDeviceSource]
    def __init__(self, hass: HomeAssistant) -> None: ...
    async def async_setup_entry(self, config_entry: ConfigEntry) -> bool: ...
    async def async_unload_entry(self, config_entry: ConfigEntry) -> bool: ...

def get_domain_data(hass: HomeAssistant) -> DlnaDmsData: ...

@dataclass
class DidlPlayMedia(PlayMedia):
    didl_metadata: didl_lite.DidlObject
    def __init__(self, url, mime_type, didl_metadata) -> None: ...

class DlnaDmsDeviceError(BrowseError, Unresolvable): ...
class DeviceConnectionError(DlnaDmsDeviceError): ...
class ActionError(DlnaDmsDeviceError): ...

def catch_request_errors(func: Callable[[_DlnaDmsDeviceMethod, str], Coroutine[Any, Any, _R]]) -> Callable[[_DlnaDmsDeviceMethod, str], Coroutine[Any, Any, _R]]: ...

class DmsDeviceSource:
    location: str | None
    _device_lock: asyncio.Lock
    _device: DmsDevice | None
    _ssdp_connect_failed: bool
    _bootid: int | None
    hass: Incomplete
    config_entry: Incomplete
    def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None: ...
    async def async_added_to_hass(self) -> None: ...
    async def async_will_remove_from_hass(self) -> None: ...
    async def async_ssdp_callback(self, info: ssdp.SsdpServiceInfo, change: ssdp.SsdpChange) -> None: ...
    async def device_connect(self) -> None: ...
    async def device_disconnect(self) -> None: ...
    @property
    def available(self) -> bool: ...
    @property
    def usn(self) -> str: ...
    @property
    def udn(self) -> str: ...
    @property
    def name(self) -> str: ...
    @property
    def source_id(self) -> str: ...
    @property
    def icon(self) -> str | None: ...
    async def async_resolve_media(self, identifier: str) -> DidlPlayMedia: ...
    async def async_browse_media(self, identifier: str | None) -> BrowseMediaSource: ...
    async def async_resolve_object(self, object_id: str) -> DidlPlayMedia: ...
    async def async_resolve_path(self, path: str) -> str: ...
    async def async_resolve_search(self, query: str) -> DidlPlayMedia: ...
    async def async_browse_object(self, object_id: str) -> BrowseMediaSource: ...
    async def async_browse_search(self, query: str) -> BrowseMediaSource: ...
    def _didl_to_play_media(self, item: didl_lite.DidlObject) -> DidlPlayMedia: ...
    def _didl_to_media_source(self, item: didl_lite.DidlObject, browsed_children: DmsDevice.BrowseResult | None = None) -> BrowseMediaSource: ...
    def _didl_thumbnail_url(self, item: didl_lite.DidlObject) -> str | None: ...
    def _make_identifier(self, action: Action, object_id: str) -> str: ...
    def _sort_criteria(self) -> list[str]: ...

class Action(StrEnum):
    OBJECT = PATH_OBJECT_ID_FLAG
    PATH = PATH_SEP
    SEARCH = PATH_SEARCH_FLAG

def _parse_identifier(identifier: str | None) -> tuple[Action | None, str]: ...
def _resource_is_streaming(resource: didl_lite.Resource) -> bool: ...
def _resource_mime_type(resource: didl_lite.Resource) -> str | None: ...
def _esc_quote(contents: str) -> str: ...
