"""
Implementations of ReadablePath and WritablePath for zip file members, for use
in pathlib tests.

ZipPathGround is also defined here. It helps establish the "ground truth"
about zip file members in tests.
"""

import errno
import io
import posixpath
import stat
import zipfile
from stat import S_IFMT, S_ISDIR, S_ISREG, S_ISLNK

from . import is_pypi

if is_pypi:
    from pathlib_abc import vfspath, PathInfo, _ReadablePath, _WritablePath
else:
    from pathlib.types import PathInfo, _ReadablePath, _WritablePath
    from pathlib._os import vfspath


class ZipPathGround:
    can_symlink = True

    def __init__(self, path_cls):
        self.path_cls = path_cls

    def setup(self, local_suffix=""):
        return self.path_cls(zip_file=zipfile.ZipFile(io.BytesIO(), "w"))

    def teardown(self, root):
        root.zip_file.close()

    def create_file(self, path, data=b''):
        path.zip_file.writestr(vfspath(path), data)

    def create_dir(self, path):
        zip_info = zipfile.ZipInfo(vfspath(path) + '/')
        zip_info.external_attr |= stat.S_IFDIR << 16
        zip_info.external_attr |= stat.FILE_ATTRIBUTE_DIRECTORY
        path.zip_file.writestr(zip_info, '')

    def create_symlink(self, path, target):
        zip_info = zipfile.ZipInfo(vfspath(path))
        zip_info.external_attr = stat.S_IFLNK << 16
        path.zip_file.writestr(zip_info, target.encode())
