1"""Functions for moving files between filesystems.
2"""
3
4from __future__ import print_function
5from __future__ import unicode_literals
6
7import typing
8
9from .copy import copy_dir
10from .copy import copy_file
11from .opener import manage_fs
12
13if typing.TYPE_CHECKING:
14    from .base import FS
15    from typing import Text, Union
16
17
18def move_fs(src_fs, dst_fs, workers=0):
19    # type: (Union[Text, FS], Union[Text, FS], int) -> None
20    """Move the contents of a filesystem to another filesystem.
21
22    Arguments:
23        src_fs (FS or str): Source filesystem (instance or URL).
24        dst_fs (FS or str): Destination filesystem (instance or URL).
25        workers (int): Use `worker` threads to copy data, or ``0`` (default) for
26            a single-threaded copy.
27
28    """
29    move_dir(src_fs, "/", dst_fs, "/", workers=workers)
30
31
32def move_file(
33    src_fs,  # type: Union[Text, FS]
34    src_path,  # type: Text
35    dst_fs,  # type: Union[Text, FS]
36    dst_path,  # type: Text
37):
38    # type: (...) -> None
39    """Move a file from one filesystem to another.
40
41    Arguments:
42        src_fs (FS or str): Source filesystem (instance or URL).
43        src_path (str): Path to a file on ``src_fs``.
44        dst_fs (FS or str); Destination filesystem (instance or URL).
45        dst_path (str): Path to a file on ``dst_fs``.
46
47    """
48    with manage_fs(src_fs) as _src_fs:
49        with manage_fs(dst_fs, create=True) as _dst_fs:
50            if _src_fs is _dst_fs:
51                # Same filesystem, may be optimized
52                _src_fs.move(src_path, dst_path, overwrite=True)
53            else:
54                # Standard copy and delete
55                with _src_fs.lock(), _dst_fs.lock():
56                    copy_file(_src_fs, src_path, _dst_fs, dst_path)
57                    _src_fs.remove(src_path)
58
59
60def move_dir(
61    src_fs,  # type: Union[Text, FS]
62    src_path,  # type: Text
63    dst_fs,  # type: Union[Text, FS]
64    dst_path,  # type: Text
65    workers=0,  # type: int
66):
67    # type: (...) -> None
68    """Move a directory from one filesystem to another.
69
70    Arguments:
71        src_fs (FS or str): Source filesystem (instance or URL).
72        src_path (str): Path to a directory on ``src_fs``
73        dst_fs (FS or str): Destination filesystem (instance or URL).
74        dst_path (str): Path to a directory on ``dst_fs``.
75        workers (int): Use `worker` threads to copy data, or ``0`` (default) for
76            a single-threaded copy.
77
78    """
79
80    def src():
81        return manage_fs(src_fs, writeable=False)
82
83    def dst():
84        return manage_fs(dst_fs, create=True)
85
86    with src() as _src_fs, dst() as _dst_fs:
87        with _src_fs.lock(), _dst_fs.lock():
88            _dst_fs.makedir(dst_path, recreate=True)
89            copy_dir(src_fs, src_path, dst_fs, dst_path, workers=workers)
90            _src_fs.removetree(src_path)
91