# Stubs for tempfile
# Ron Murawski <ron@horizonchess.com>

# based on http://docs.python.org/3.3/library/tempfile.html

import sys
from types import TracebackType
from typing import Any, AnyStr, Generic, IO, Iterable, Iterator, List, Optional, Tuple, Type

# global variables
TMP_MAX: int
tempdir = ...  # type: Optional[str]
template = ...  # type: str


if sys.version_info >= (3, 5):
    def TemporaryFile(
        mode: str = ..., buffering: int = ..., encoding: Optional[str] = ...,
        newline: Optional[str] = ..., suffix: Optional[AnyStr] = ..., prefix: Optional[AnyStr] = ...,
        dir: Optional[AnyStr] = ...
    ) -> IO[Any]:
        ...
    def NamedTemporaryFile(
        mode: str = ..., buffering: int = ..., encoding: Optional[str] = ...,
        newline: Optional[str] = ..., suffix: Optional[AnyStr] = ..., prefix: Optional[AnyStr] = ...,
        dir: Optional[AnyStr] = ..., delete: bool = ...
    ) -> IO[Any]:
        ...

    # It does not actually derive from IO[AnyStr], but it does implement the
    # protocol.
    class SpooledTemporaryFile(IO[AnyStr]):
        def __init__(self, max_size: int = ..., mode: str = ...,
                     buffering: int = ..., encoding: Optional[str] = ...,
                     newline: Optional[str] = ..., suffix: Optional[str] = ...,
                     prefix: Optional[str] = ..., dir: Optional[str] = ...
                     ) -> None: ...
        def rollover(self) -> None: ...
        def __enter__(self) -> SpooledTemporaryFile: ...
        def __exit__(self, exc_type: Optional[Type[BaseException]],
                     exc_val: Optional[BaseException],
                     exc_tb: Optional[TracebackType]) -> bool: ...

        # These methods are copied from the abstract methods of IO, because
        # SpooledTemporaryFile implements IO.
        # See also https://github.com/python/typeshed/pull/2452#issuecomment-420657918.
        def close(self) -> None: ...
        def fileno(self) -> int: ...
        def flush(self) -> None: ...
        def isatty(self) -> bool: ...
        def read(self, n: int = ...) -> AnyStr: ...
        def readable(self) -> bool: ...
        def readline(self, limit: int = ...) -> AnyStr: ...
        def readlines(self, hint: int = ...) -> List[AnyStr]: ...
        def seek(self, offset: int, whence: int = ...) -> int: ...
        def seekable(self) -> bool: ...
        def tell(self) -> int: ...
        def truncate(self, size: Optional[int] = ...) -> int: ...
        def writable(self) -> bool: ...
        def write(self, s: AnyStr) -> int: ...
        def writelines(self, lines: Iterable[AnyStr]) -> None: ...
        def __next__(self) -> AnyStr: ...
        def __iter__(self) -> Iterator[AnyStr]: ...

    class TemporaryDirectory(Generic[AnyStr]):
        name = ...  # type: str
        def __init__(self, suffix: Optional[AnyStr] = ..., prefix: Optional[AnyStr] = ...,
                     dir: Optional[AnyStr] = ...) -> None: ...
        def cleanup(self) -> None: ...
        def __enter__(self) -> AnyStr: ...
        def __exit__(self, exc_type: Optional[Type[BaseException]],
                     exc_val: Optional[BaseException],
                     exc_tb: Optional[TracebackType]) -> bool: ...

    def mkstemp(suffix: Optional[AnyStr] = ..., prefix: Optional[AnyStr] = ..., dir: Optional[AnyStr] = ...,
                text: bool = ...) -> Tuple[int, AnyStr]: ...
    def mkdtemp(suffix: Optional[AnyStr] = ..., prefix: Optional[AnyStr] = ...,
                dir: Optional[str] = ...) -> AnyStr: ...
    def mktemp(suffix: Optional[AnyStr] = ..., prefix: Optional[AnyStr] = ..., dir: Optional[AnyStr] = ...) -> AnyStr: ...

    def gettempdirb() -> bytes: ...
    def gettempprefixb() -> bytes: ...
else:
    def TemporaryFile(
        mode: str = ..., buffering: int = ..., encoding: Optional[str] = ...,
        newline: Optional[str] = ..., suffix: str = ..., prefix: str = ...,
        dir: Optional[str] = ...
    ) -> IO[Any]:
        ...
    def NamedTemporaryFile(
        mode: str = ..., buffering: int = ..., encoding: Optional[str] = ...,
        newline: Optional[str] = ..., suffix: str = ..., prefix: str = ...,
        dir: Optional[str] = ..., delete: bool = ...
    ) -> IO[Any]:
        ...
    def SpooledTemporaryFile(
        max_size: int = ..., mode: str = ..., buffering: int = ...,
        encoding: str = ..., newline: str = ..., suffix: str = ...,
        prefix: str = ..., dir: Optional[str] = ...
    ) -> IO[Any]:
        ...

    class TemporaryDirectory:
        name = ...  # type: str
        def __init__(self, suffix: str = ..., prefix: str = ...,
                     dir: Optional[str] = ...) -> None: ...
        def cleanup(self) -> None: ...
        def __enter__(self) -> str: ...
        def __exit__(self, exc_type: Optional[Type[BaseException]],
                     exc_val: Optional[BaseException],
                     exc_tb: Optional[TracebackType]) -> bool: ...

    def mkstemp(suffix: str = ..., prefix: str = ..., dir: Optional[str] = ...,
                text: bool = ...) -> Tuple[int, str]: ...
    def mkdtemp(suffix: str = ..., prefix: str = ...,
                dir: Optional[str] = ...) -> str: ...
    def mktemp(suffix: str = ..., prefix: str = ..., dir: Optional[str] = ...) -> str: ...

def gettempdir() -> str: ...
def gettempprefix() -> str: ...
