"""pathlib_abc exports for compatibility with pathlib."""

import sys
from abc import ABC
from abc import abstractmethod
from typing import Any
from typing import BinaryIO
from typing import Callable
from typing import Iterator
from typing import Literal
from typing import Protocol
from typing import Sequence
from typing import TextIO
from typing import TypeVar
from typing import runtime_checkable

if sys.version_info > (3, 11):
    from typing import Self
else:
    from typing_extensions import Self

class JoinablePath(ABC):
    __slots__ = ()

    @property
    @abstractmethod
    def parser(self) -> PathParser: ...
    @abstractmethod
    def with_segments(self, *pathsegments: str) -> Self: ...
    @abstractmethod
    def __vfspath__(self) -> str: ...
    @property
    def anchor(self) -> str: ...
    @property
    def name(self) -> str: ...
    @property
    def suffix(self) -> str: ...
    @property
    def suffixes(self) -> list[str]: ...
    @property
    def stem(self) -> str: ...
    def with_name(self, name: str) -> Self: ...
    def with_stem(self, stem: str) -> Self: ...
    def with_suffix(self, suffix: str) -> Self: ...
    @property
    def parts(self) -> Sequence[str]: ...
    def joinpath(self, *pathsegments: str) -> Self: ...
    def __truediv__(self, key: str) -> Self: ...
    def __rtruediv__(self, key: str) -> Self: ...
    @property
    def parent(self) -> Self: ...
    @property
    def parents(self) -> Sequence[Self]: ...
    def full_match(self, pattern: str) -> bool: ...

OnErrorCallable = Callable[[Exception], Any]
T = TypeVar("T", bound="WritablePath")

class ReadablePath(JoinablePath):
    __slots__ = ()

    @property
    @abstractmethod
    def info(self) -> PathInfo: ...
    @abstractmethod
    def __open_reader__(self) -> BinaryIO: ...
    def read_bytes(self) -> bytes: ...
    def read_text(
        self,
        encoding: str | None = ...,
        errors: str | None = ...,
        newline: str | None = ...,
    ) -> str: ...
    @abstractmethod
    def iterdir(self) -> Iterator[Self]: ...
    def glob(self, pattern: str, *, recurse_symlinks: bool = ...) -> Iterator[Self]: ...
    def walk(
        self,
        top_down: bool = ...,
        on_error: OnErrorCallable | None = ...,
        follow_symlinks: bool = ...,
    ) -> Iterator[tuple[Self, list[str], list[str]]]: ...
    @abstractmethod
    def readlink(self) -> Self: ...
    def copy(self, target: T, **kwargs: Any) -> T: ...
    def copy_into(self, target_dir: T, **kwargs: Any) -> T: ...

class WritablePath(JoinablePath):
    __slots__ = ()

    @abstractmethod
    def symlink_to(
        self, target: ReadablePath, target_is_directory: bool = ...
    ) -> None: ...
    @abstractmethod
    def mkdir(self) -> None: ...
    @abstractmethod
    def __open_writer__(self, mode: Literal["a", "w", "x"]) -> BinaryIO: ...
    def write_bytes(self, data: bytes) -> int: ...
    def write_text(
        self,
        data: str,
        encoding: str | None = ...,
        errors: str | None = ...,
        newline: str | None = ...,
    ) -> int: ...
    def _copy_from(self, source: ReadablePath, follow_symlinks: bool = ...) -> None: ...

@runtime_checkable
class PathParser(Protocol):
    sep: str
    altsep: str | None

    def split(self, path: str) -> tuple[str, str]: ...
    def splitext(self, path: str) -> tuple[str, str]: ...
    def normcase(self, path: str) -> str: ...

@runtime_checkable
class PathInfo(Protocol):
    def exists(self, *, follow_symlinks: bool = True) -> bool: ...
    def is_dir(self, *, follow_symlinks: bool = True) -> bool: ...
    def is_file(self, *, follow_symlinks: bool = True) -> bool: ...
    def is_symlink(self) -> bool: ...

class SupportsOpenReader(Protocol):
    def __open_reader__(self) -> BinaryIO: ...

class SupportsOpenWriter(Protocol):
    def __open_writer__(self, mode: Literal["a", "w", "x"]) -> BinaryIO: ...

class SupportsOpenUpdater(Protocol):
    def __open_updater__(self, mode: Literal["r+", "w+", "+r", "+w"]) -> BinaryIO: ...

def vfsopen(
    obj: SupportsOpenReader | SupportsOpenWriter | SupportsOpenUpdater,
    mode="r",
    buffering: int = -1,
    encoding: str | None = None,
    errors: str | None = None,
    newline: str | None = None,
) -> BinaryIO | TextIO: ...

class SupportsVFSPath(Protocol):
    def __vfspath__(self) -> str: ...

def vfspath(obj: SupportsVFSPath) -> str: ...
