import sys
from collections.abc import Callable
from enum import Enum
from typing import Any, AnyStr, NoReturn

from pyfakefs.fake_file import AnyFile, AnyFileWrapper, FakeDirectory, FakeFile
from pyfakefs.helpers import AnyPath, AnyString

if sys.platform.startswith("linux"):
    _MAX_LINK_DEPTH = ...
else:
    _MAX_LINK_DEPTH = ...

class OSType(Enum):
    LINUX = ...
    MACOS = ...
    WINDOWS = ...

FakeNullFile = ...
FakeFileFromRealFile = ...
FakeDirectoryFromRealDirectory = ...
FakeFileWrapper = ...
StandardStreamWrapper = ...
FakeDirWrapper = ...
FakePipeWrapper = ...
FakePathModule = ...
FakeOsModule = ...
FakeFileOpen = ...
FakeIoModule = ...
if sys.platform != "win32":
    FakeFcntlModule = ...
PatchMode = ...
is_root = ...
set_uid = ...
set_gid = ...
reset_ids = ...

class FakeFilesystem:
    def __init__(
        self,
        path_separator: str = ...,
        total_size: int | None = ...,
        patcher: Any = ...,
    ) -> None: ...
    @property
    def is_linux(self) -> bool: ...
    @property
    def is_windows_fs(self) -> bool: ...
    @is_windows_fs.setter
    def is_windows_fs(self, value: bool) -> None: ...
    @property
    def is_macos(self) -> bool: ...
    @is_macos.setter
    def is_macos(self, value: bool) -> None: ...
    @property
    def cwd(self) -> str: ...
    @cwd.setter
    def cwd(self, value: str) -> None: ...
    @property
    def root_dir(self) -> FakeDirectory: ...
    @property
    def root_dir_name(self) -> str: ...
    @property
    def os(self) -> OSType: ...
    @os.setter
    def os(self, value: OSType) -> None: ...
    def reset(self, total_size: int | None = ...) -> None: ...
    def pause(self) -> None: ...
    def resume(self) -> None: ...
    def clear_cache(self) -> None: ...
    def line_separator(self) -> str: ...
    def raise_os_error(
        self,
        err_no: int,
        filename: AnyString | None = ...,
        winerror: int | None = ...,
    ) -> NoReturn: ...
    def get_path_separator(self, path: AnyStr) -> AnyStr: ...
    def starts_with_sep(self, path: AnyStr) -> bool: ...
    def add_mount_point(
        self, path: AnyStr, total_size: int | None = ..., can_exist: bool = ...
    ) -> dict: ...
    def get_disk_usage(self, path: AnyStr | None = ...) -> tuple[int, int, int]: ...
    def set_disk_usage(self, total_size: int, path: AnyStr | None = ...) -> None: ...
    def change_disk_usage(
        self, usage_change: int, file_path: AnyStr, st_dev: int
    ) -> None: ...
    def stat(self, entry_path: AnyStr, follow_symlinks: bool = ...): ...
    def raise_for_filepath_ending_with_separator(
        self,
        entry_path: AnyStr,
        file_object: FakeFile,
        follow_symlinks: bool = ...,
        macos_handling: bool = ...,
    ) -> None: ...
    def chmod(
        self,
        path: AnyStr,
        mode: int,
        follow_symlinks: bool = ...,
        force_unix_mode: bool = ...,
    ) -> None: ...
    def utime(
        self,
        path: AnyStr,
        times: tuple[int | float, int | float] | None = ...,
        *,
        ns: tuple[int, int] | None = ...,
        follow_symlinks: bool = ...,
    ) -> None: ...
    def get_open_file(self, file_des: int) -> AnyFileWrapper: ...
    def has_open_file(self, file_object: FakeFile) -> bool: ...
    def normcase(self, path: AnyStr) -> AnyStr: ...
    def normpath(self, path: AnyStr) -> AnyStr: ...
    def absnormpath(self, path: AnyStr) -> AnyStr: ...
    def splitpath(self, path: AnyStr) -> tuple[AnyStr, AnyStr]: ...
    def splitdrive(self, path: AnyStr) -> tuple[AnyStr, AnyStr]: ...
    def splitroot(self, path: AnyStr): ...
    def joinpaths(self, *paths: AnyStr) -> AnyStr: ...
    def starts_with_drive_letter(self, file_path: AnyStr) -> bool: ...
    def replace_windows_root(self, path: AnyStr) -> AnyStr: ...
    def is_mount_point(self, file_path: AnyStr) -> bool: ...
    def ends_with_path_separator(self, path: int | AnyPath) -> bool: ...
    def is_filepath_ending_with_separator(self, path: AnyStr) -> bool: ...
    def exists(self, file_path: AnyPath, check_link: bool = ...) -> bool: ...
    def resolve_path(self, file_path: AnyStr, allow_fd: bool = ...) -> AnyStr: ...
    def get_object_from_normpath(
        self, file_path: AnyPath, check_read_perm: bool = ..., check_owner: bool = ...
    ) -> AnyFile: ...
    def get_object(
        self, file_path: AnyPath, check_read_perm: bool = ...
    ) -> FakeFile: ...
    def resolve(
        self,
        file_path: AnyStr,
        follow_symlinks: bool = ...,
        allow_fd: bool = ...,
        check_read_perm: bool = ...,
        check_owner: bool = ...,
    ) -> FakeFile: ...
    def lresolve(self, path: AnyPath) -> FakeFile: ...
    def add_object(self, file_path: AnyStr, file_object: AnyFile) -> None: ...
    def rename(
        self, old_file_path: AnyPath, new_file_path: AnyPath, force_replace: bool = ...
    ) -> None: ...
    def remove_object(self, file_path: AnyStr) -> None: ...
    def make_string_path(self, path: AnyPath) -> AnyStr: ...
    def create_dir(
        self, directory_path: AnyPath, perm_bits: int = ...
    ) -> FakeDirectory: ...
    def create_file(
        self,
        file_path: AnyPath[AnyStr],
        st_mode: int = ...,
        contents: AnyString = ...,
        st_size: int | None = ...,
        create_missing_dirs: bool = ...,
        apply_umask: bool = ...,
        encoding: str | None = ...,
        errors: str | None = ...,
        side_effect: Callable[[FakeFile], Any] | None = ...,
    ) -> FakeFile: ...
    def add_real_file(
        self,
        source_path: AnyPath[AnyStr],
        read_only: bool = ...,
        target_path: AnyPath[AnyStr] | None = ...,
    ) -> FakeFile: ...
    def add_real_symlink(
        self, source_path: AnyPath, target_path: AnyPath | None = ...
    ) -> FakeFile: ...
    def add_real_directory(
        self,
        source_path: AnyPath[AnyStr],
        read_only: bool = ...,
        lazy_read: bool = ...,
        target_path: AnyPath[AnyStr] | None = ...,
    ) -> FakeDirectory: ...
    def add_real_paths(
        self, path_list: list[AnyStr], read_only: bool = ..., lazy_dir_read: bool = ...
    ) -> None: ...
    def create_file_internally(
        self,
        file_path: AnyPath,
        st_mode: int = ...,
        contents: AnyString = ...,
        st_size: int | None = ...,
        create_missing_dirs: bool = ...,
        apply_umask: bool = ...,
        encoding: str | None = ...,
        errors: str | None = ...,
        read_from_real_fs: bool = ...,
        side_effect: Callable | None = ...,
    ) -> FakeFile: ...
    def create_symlink(
        self, file_path: AnyPath, link_target: AnyPath, create_missing_dirs: bool = ...
    ) -> FakeFile: ...
    def create_link(
        self,
        old_path: AnyPath,
        new_path: AnyPath,
        follow_symlinks: bool = ...,
        create_missing_dirs: bool = ...,
    ) -> FakeFile: ...
    def link(
        self, old_path: AnyPath, new_path: AnyPath, follow_symlinks: bool = ...
    ) -> FakeFile: ...
    def readlink(self, path: AnyPath) -> str: ...
    def makedir(self, dir_path: AnyPath, mode: int = ...) -> None: ...
    def makedirs(
        self, dir_name: AnyStr, mode: int = ..., exist_ok: bool = ...
    ) -> None: ...
    def isdir(self, path: AnyPath, follow_symlinks: bool = ...) -> bool: ...
    def isfile(self, path: AnyPath, follow_symlinks: bool = ...) -> bool: ...
    def islink(self, path: AnyPath) -> bool: ...
    def confirmdir(
        self, target_directory: AnyStr, check_owner: bool = ...
    ) -> FakeDirectory: ...
    def remove(self, path: AnyStr) -> None: ...
    def rmdir(self, target_directory: AnyStr, allow_symlink: bool = ...) -> None: ...
    def listdir(self, target_directory: AnyStr) -> list[AnyStr]: ...
    def __str__(self) -> str: ...
