import os
from _typeshed import Incomplete
from collections.abc import Callable as Callable, Iterable, Iterator
from pathlib import Path
from pydicom.charset import default_encoding as default_encoding
from pydicom.datadict import dictionary_description as dictionary_description, tag_for_keyword as tag_for_keyword
from pydicom.dataelem import DataElement as DataElement
from pydicom.dataset import Dataset as Dataset, FileDataset as FileDataset, FileMetaDataset as FileMetaDataset
from pydicom.filebase import DicomBytesIO as DicomBytesIO, DicomFileLike as DicomFileLike
from pydicom.filereader import dcmread as dcmread
from pydicom.filewriter import write_data_element as write_data_element, write_dataset as write_dataset, write_file_meta_info as write_file_meta_info
from pydicom.misc import warn_and_log as warn_and_log
from pydicom.tag import BaseTag as BaseTag, Tag as Tag
from pydicom.uid import ExplicitVRLittleEndian as ExplicitVRLittleEndian, ImplicitVRLittleEndian as ImplicitVRLittleEndian, MediaStorageDirectoryStorage as MediaStorageDirectoryStorage, UID as UID, generate_uid as generate_uid
from typing import Any

def generate_filename(prefix: str = '', start: int = 0, alphanumeric: bool = False) -> Iterator[str]: ...
def is_conformant_file_id(path: Path) -> bool: ...

class RecordNode(Iterable['RecordNode']):
    children: Incomplete
    instance: Incomplete
    def __init__(self, record: Dataset | None = None) -> None: ...
    def add(self, leaf: RecordNode) -> None: ...
    @property
    def ancestors(self) -> list['RecordNode']: ...
    @property
    def component(self) -> str: ...
    def __contains__(self, key: str | RecordNode) -> bool: ...
    def __delitem__(self, key: str | RecordNode) -> None: ...
    @property
    def depth(self) -> int: ...
    @property
    def file_set(self) -> FileSet: ...
    def __getitem__(self, key: str | RecordNode) -> RecordNode: ...
    @property
    def has_instance(self) -> bool: ...
    @property
    def index(self) -> int: ...
    @property
    def is_root(self) -> bool: ...
    def __iter__(self) -> Iterator['RecordNode']: ...
    @property
    def key(self) -> str: ...
    @property
    def next(self) -> RecordNode | None: ...
    @property
    def parent(self) -> RecordNode: ...
    @parent.setter
    def parent(self, node: RecordNode) -> None: ...
    def prettify(self, indent_char: str = '  ') -> list[str]: ...
    @property
    def previous(self) -> RecordNode | None: ...
    @property
    def record_type(self) -> str: ...
    def remove(self, node: RecordNode) -> None: ...
    def reverse(self) -> Iterable['RecordNode']: ...
    @property
    def root(self) -> RecordNode: ...

class RootNode(RecordNode):
    def __init__(self, fs: FileSet) -> None: ...
    @property
    def file_set(self) -> FileSet: ...
    @property
    def is_root(self) -> bool: ...

class FileInstance:
    node: Incomplete
    def __init__(self, node: RecordNode) -> None: ...
    def __contains__(self, name: str | int) -> bool: ...
    @property
    def FileID(self) -> str: ...
    @property
    def file_set(self) -> FileSet: ...
    @property
    def for_addition(self) -> bool: ...
    @property
    def for_moving(self) -> bool: ...
    @property
    def for_removal(self) -> bool: ...
    def __getattribute__(self, name: str) -> Any: ...
    def __getitem__(self, key: str | int) -> DataElement: ...
    @property
    def is_private(self) -> bool: ...
    @property
    def is_staged(self) -> bool: ...
    def load(self) -> Dataset: ...
    @property
    def path(self) -> str: ...
    @property
    def SOPClassUID(self) -> UID: ...
    @property
    def SOPInstanceUID(self) -> UID: ...
    @property
    def TransferSyntaxUID(self) -> UID: ...
DSPathType = Dataset | str | os.PathLike

class FileSet:
    def __init__(self, ds: DSPathType | None = None) -> None: ...
    def add(self, ds_or_path: DSPathType) -> FileInstance: ...
    def add_custom(self, ds_or_path: DSPathType, leaf: RecordNode) -> FileInstance: ...
    def clear(self) -> None: ...
    def copy(self, path: str | os.PathLike, force_implicit: bool = False) -> FileSet: ...
    @property
    def descriptor_character_set(self) -> str | None: ...
    @descriptor_character_set.setter
    def descriptor_character_set(self, val: str | None) -> None: ...
    @property
    def descriptor_file_id(self) -> str | None: ...
    @descriptor_file_id.setter
    def descriptor_file_id(self, val: str | None) -> None: ...
    def find(self, load: bool = False, **kwargs: Any) -> list[FileInstance]: ...
    def find_values(self, elements: str | int | list[str | int], instances: list[FileInstance] | None = None, load: bool = False) -> list[Any] | dict[str | int, list[Any]]: ...
    @property
    def ID(self) -> str | None: ...
    @ID.setter
    def ID(self, val: str | None) -> None: ...
    @property
    def is_staged(self) -> bool: ...
    def __iter__(self) -> Iterator[FileInstance]: ...
    def __len__(self) -> int: ...
    def load(self, ds_or_path: DSPathType, include_orphans: bool = True, raise_orphans: bool = False) -> None: ...
    @property
    def path(self) -> str | None: ...
    def remove(self, instance: FileInstance | list[FileInstance]) -> None: ...
    @property
    def UID(self) -> UID: ...
    @UID.setter
    def UID(self, uid: UID) -> None: ...
    def write(self, path: str | os.PathLike | None = None, use_existing: bool = False, force_implicit: bool = False) -> None: ...

DIRECTORY_RECORDERS: Incomplete
