import _typeshed
import enum
import modal.client
import modal_proto.api_pb2
import typing
import typing_extensions

T = typing.TypeVar("T")

async def _delete_bytes(
    file: _FileIO, start: typing.Optional[int] = None, end: typing.Optional[int] = None
) -> None: ...
async def _replace_bytes(
    file: _FileIO, data: bytes, start: typing.Optional[int] = None, end: typing.Optional[int] = None
) -> None: ...

class FileWatchEventType(enum.Enum):
    Unknown = "Unknown"
    Access = "Access"
    Create = "Create"
    Modify = "Modify"
    Remove = "Remove"

class FileWatchEvent:
    paths: list[str]
    type: FileWatchEventType

    def __init__(self, paths: list[str], type: FileWatchEventType) -> None: ...
    def __repr__(self): ...
    def __eq__(self, other): ...

class _FileIO(typing.Generic[T]):
    _task_id: str
    _file_descriptor: str
    _client: modal.client._Client
    _watch_output_buffer: list[typing.Optional[bytes]]

    def __init__(self, client: modal.client._Client, task_id: str) -> None: ...
    def _validate_mode(self, mode: str) -> None: ...
    def _handle_error(self, error: modal_proto.api_pb2.SystemErrorMessage) -> None: ...
    def _consume_output(self, exec_id: str) -> typing.AsyncIterator[typing.Optional[bytes]]: ...
    async def _consume_watch_output(self, exec_id: str) -> None: ...
    async def _parse_watch_output(self, event: bytes) -> typing.Optional[FileWatchEvent]: ...
    async def _wait(self, exec_id: str) -> bytes: ...
    def _validate_type(self, data: typing.Union[bytes, str]) -> None: ...
    async def _open_file(self, path: str, mode: str) -> None: ...
    @classmethod
    async def create(
        cls,
        path: str,
        mode: typing.Union[_typeshed.OpenTextMode, _typeshed.OpenBinaryMode],
        client: modal.client._Client,
        task_id: str,
    ) -> _FileIO: ...
    async def _make_read_request(self, n: typing.Optional[int]) -> bytes: ...
    async def read(self, n: typing.Optional[int] = None) -> T: ...
    async def readline(self) -> T: ...
    async def readlines(self) -> typing.Sequence[T]: ...
    async def write(self, data: typing.Union[bytes, str]) -> None: ...
    async def flush(self) -> None: ...
    def _get_whence(self, whence: int): ...
    async def seek(self, offset: int, whence: int = 0) -> None: ...
    @classmethod
    async def ls(cls, path: str, client: modal.client._Client, task_id: str) -> list[str]: ...
    @classmethod
    async def mkdir(cls, path: str, client: modal.client._Client, task_id: str, parents: bool = False) -> None: ...
    @classmethod
    async def rm(cls, path: str, client: modal.client._Client, task_id: str, recursive: bool = False) -> None: ...
    @classmethod
    def watch(
        cls,
        path: str,
        client: modal.client._Client,
        task_id: str,
        filter: typing.Optional[list[FileWatchEventType]] = None,
        recursive: bool = False,
        timeout: typing.Optional[int] = None,
    ) -> typing.AsyncIterator[FileWatchEvent]: ...
    async def _close(self) -> None: ...
    async def close(self) -> None: ...
    def _check_writable(self) -> None: ...
    def _check_readable(self) -> None: ...
    def _check_closed(self) -> None: ...
    async def __aenter__(self) -> _FileIO: ...
    async def __aexit__(self, exc_type, exc_value, traceback) -> None: ...

class __delete_bytes_spec(typing_extensions.Protocol):
    def __call__(self, file: FileIO, start: typing.Optional[int] = None, end: typing.Optional[int] = None) -> None: ...
    async def aio(self, file: FileIO, start: typing.Optional[int] = None, end: typing.Optional[int] = None) -> None: ...

delete_bytes: __delete_bytes_spec

class __replace_bytes_spec(typing_extensions.Protocol):
    def __call__(
        self, file: FileIO, data: bytes, start: typing.Optional[int] = None, end: typing.Optional[int] = None
    ) -> None: ...
    async def aio(
        self, file: FileIO, data: bytes, start: typing.Optional[int] = None, end: typing.Optional[int] = None
    ) -> None: ...

replace_bytes: __replace_bytes_spec

SUPERSELF = typing.TypeVar("SUPERSELF", covariant=True)

T_INNER = typing.TypeVar("T_INNER", covariant=True)

class FileIO(typing.Generic[T]):
    _task_id: str
    _file_descriptor: str
    _client: modal.client.Client
    _watch_output_buffer: list[typing.Optional[bytes]]

    def __init__(self, client: modal.client.Client, task_id: str) -> None: ...
    def _validate_mode(self, mode: str) -> None: ...
    def _handle_error(self, error: modal_proto.api_pb2.SystemErrorMessage) -> None: ...

    class ___consume_output_spec(typing_extensions.Protocol[SUPERSELF]):
        def __call__(self, exec_id: str) -> typing.Iterator[typing.Optional[bytes]]: ...
        def aio(self, exec_id: str) -> typing.AsyncIterator[typing.Optional[bytes]]: ...

    _consume_output: ___consume_output_spec[typing_extensions.Self]

    class ___consume_watch_output_spec(typing_extensions.Protocol[SUPERSELF]):
        def __call__(self, exec_id: str) -> None: ...
        async def aio(self, exec_id: str) -> None: ...

    _consume_watch_output: ___consume_watch_output_spec[typing_extensions.Self]

    class ___parse_watch_output_spec(typing_extensions.Protocol[SUPERSELF]):
        def __call__(self, event: bytes) -> typing.Optional[FileWatchEvent]: ...
        async def aio(self, event: bytes) -> typing.Optional[FileWatchEvent]: ...

    _parse_watch_output: ___parse_watch_output_spec[typing_extensions.Self]

    class ___wait_spec(typing_extensions.Protocol[SUPERSELF]):
        def __call__(self, exec_id: str) -> bytes: ...
        async def aio(self, exec_id: str) -> bytes: ...

    _wait: ___wait_spec[typing_extensions.Self]

    def _validate_type(self, data: typing.Union[bytes, str]) -> None: ...

    class ___open_file_spec(typing_extensions.Protocol[SUPERSELF]):
        def __call__(self, path: str, mode: str) -> None: ...
        async def aio(self, path: str, mode: str) -> None: ...

    _open_file: ___open_file_spec[typing_extensions.Self]

    @classmethod
    def create(
        cls,
        path: str,
        mode: typing.Union[_typeshed.OpenTextMode, _typeshed.OpenBinaryMode],
        client: modal.client.Client,
        task_id: str,
    ) -> FileIO: ...

    class ___make_read_request_spec(typing_extensions.Protocol[SUPERSELF]):
        def __call__(self, n: typing.Optional[int]) -> bytes: ...
        async def aio(self, n: typing.Optional[int]) -> bytes: ...

    _make_read_request: ___make_read_request_spec[typing_extensions.Self]

    class __read_spec(typing_extensions.Protocol[T_INNER, SUPERSELF]):
        def __call__(self, n: typing.Optional[int] = None) -> T_INNER: ...
        async def aio(self, n: typing.Optional[int] = None) -> T_INNER: ...

    read: __read_spec[T, typing_extensions.Self]

    class __readline_spec(typing_extensions.Protocol[T_INNER, SUPERSELF]):
        def __call__(self) -> T_INNER: ...
        async def aio(self) -> T_INNER: ...

    readline: __readline_spec[T, typing_extensions.Self]

    class __readlines_spec(typing_extensions.Protocol[T_INNER, SUPERSELF]):
        def __call__(self) -> typing.Sequence[T_INNER]: ...
        async def aio(self) -> typing.Sequence[T_INNER]: ...

    readlines: __readlines_spec[T, typing_extensions.Self]

    class __write_spec(typing_extensions.Protocol[SUPERSELF]):
        def __call__(self, data: typing.Union[bytes, str]) -> None: ...
        async def aio(self, data: typing.Union[bytes, str]) -> None: ...

    write: __write_spec[typing_extensions.Self]

    class __flush_spec(typing_extensions.Protocol[SUPERSELF]):
        def __call__(self) -> None: ...
        async def aio(self) -> None: ...

    flush: __flush_spec[typing_extensions.Self]

    def _get_whence(self, whence: int): ...

    class __seek_spec(typing_extensions.Protocol[SUPERSELF]):
        def __call__(self, offset: int, whence: int = 0) -> None: ...
        async def aio(self, offset: int, whence: int = 0) -> None: ...

    seek: __seek_spec[typing_extensions.Self]

    @classmethod
    def ls(cls, path: str, client: modal.client.Client, task_id: str) -> list[str]: ...
    @classmethod
    def mkdir(cls, path: str, client: modal.client.Client, task_id: str, parents: bool = False) -> None: ...
    @classmethod
    def rm(cls, path: str, client: modal.client.Client, task_id: str, recursive: bool = False) -> None: ...
    @classmethod
    def watch(
        cls,
        path: str,
        client: modal.client.Client,
        task_id: str,
        filter: typing.Optional[list[FileWatchEventType]] = None,
        recursive: bool = False,
        timeout: typing.Optional[int] = None,
    ) -> typing.Iterator[FileWatchEvent]: ...

    class ___close_spec(typing_extensions.Protocol[SUPERSELF]):
        def __call__(self) -> None: ...
        async def aio(self) -> None: ...

    _close: ___close_spec[typing_extensions.Self]

    class __close_spec(typing_extensions.Protocol[SUPERSELF]):
        def __call__(self) -> None: ...
        async def aio(self) -> None: ...

    close: __close_spec[typing_extensions.Self]

    def _check_writable(self) -> None: ...
    def _check_readable(self) -> None: ...
    def _check_closed(self) -> None: ...
    def __enter__(self) -> FileIO: ...
    async def __aenter__(self) -> FileIO: ...
    def __exit__(self, exc_type, exc_value, traceback) -> None: ...
    async def __aexit__(self, exc_type, exc_value, traceback) -> None: ...
