# Copyright (C) 2007-2021, Stefan Schwarzer <sschwarzer@sschwarzer.net>
# and ftputil contributors (see `doc/contributors.txt`)
# See the file LICENSE for licensing terms.

import io
import ntpath
import os
import shutil

import ftputil
import ftputil.path_encoding
import ftputil.sync


# Assume the test subdirectories are or will be in the current directory.
TEST_ROOT = os.getcwd()


class TestLocalToLocal:
    def setup_method(self, method):
        if not os.path.exists("test_empty"):
            os.mkdir("test_empty")
        if os.path.exists("test_target"):
            shutil.rmtree("test_target")
        os.mkdir("test_target")

    def test_sync_empty_dir(self):
        source = ftputil.sync.LocalHost()
        target = ftputil.sync.LocalHost()
        syncer = ftputil.sync.Syncer(source, target)
        source_dir = os.path.join(TEST_ROOT, "test_empty")
        target_dir = os.path.join(TEST_ROOT, "test_target")
        syncer.sync(source_dir, target_dir)

    def test_source_with_and_target_without_slash(self):
        source = ftputil.sync.LocalHost()
        target = ftputil.sync.LocalHost()
        syncer = ftputil.sync.Syncer(source, target)
        source_dir = os.path.join(TEST_ROOT, "test_source/")
        target_dir = os.path.join(TEST_ROOT, "test_target")
        syncer.sync(source_dir, target_dir)


# Helper classes for `TestUploadFromWindows`


class LocalWindowsHost(ftputil.sync.LocalHost):
    def __init__(self):
        self.path = ntpath
        self.sep = "\\"

    def open(self, path, mode):
        # Just return a dummy file object.
        return io.StringIO("")

    def walk(self, root):
        """
        Return a list of tuples as `os.walk`, but use tuples as if the
        directory structure was

        <root>
            dir1
                dir11
                file1
                file2

        where <root> is the string passed in as `root`.
        """
        join = ntpath.join
        return [
            (root, [join(root, "dir1")], []),
            (join(root, "dir1"), ["dir11"], ["file1", "file2"]),
        ]


class DummyFTPSession:
    def pwd(self):
        return "/"


class DummyFTPPath:
    def abspath(self, path):
        # Don't care here if the path is absolute or not.
        return path

    def isdir(self, path):
        return "dir" in path

    def isfile(self, path):
        return "file" in path


class ArgumentCheckingFTPHost(ftputil.FTPHost):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.path = DummyFTPPath()

    def _make_session(self, *args, **kwargs):
        self._encoding = ftputil.path_encoding.DEFAULT_ENCODING
        return DummyFTPSession()

    def mkdir(self, path):
        assert "\\" not in path

    def open(self, path, mode):
        assert "\\" not in path
        return io.StringIO("")


class TestUploadFromWindows:
    def test_no_mixed_separators(self):
        source = LocalWindowsHost()
        target = ArgumentCheckingFTPHost()
        local_root = ntpath.join("some", "directory")
        syncer = ftputil.sync.Syncer(source, target)
        # If the following call raises any `AssertionError`s, the test
        # framework will catch them and show them.
        syncer.sync(local_root, "not_used_by_ArgumentCheckingFTPHost")
