# Path: foil/ftp.py
# def parse_line(line: str, char_index=0) -> Tuple[ListingType, str]:
#     """Parse FTP directory listing into (type, filename)."""
# 
#     entry_name = str.rpartition(line, ' ')[-1]
#     entry_type = LISTING_FLAG_MAP.get(line[char_index], ListingType.other)
#     return entry_type, entry_name
# 
# def ftp_walk(ftpconn: FTP, rootpath=''):
#     """Recursively traverse an ftp directory to discovery directory listing."""
# 
#     current_directory = rootpath
# 
#     try:
#         directories, files = directory_listing(ftpconn, current_directory)
#     except ftplib.error_perm:
#         return
# 
#     # Yield before recursion
#     yield current_directory, directories, files
# 
#     # Recurse into sub-directories
#     for name in directories:
#         new_path = os.path.join(current_directory, name)
# 
#         for entry in ftp_walk(ftpconn, rootpath=new_path):
#             yield entry
#     else:
#         return
# 
# def ftp_listing_paths(ftpconn: FTP, root: str) -> Iterable[str]:
#     """Generate the full file paths from a root path."""
# 
#     for current_path, dirs, files in ftp_walk(ftpconn, root):
#         yield from (os.path.join(current_path, file) for file in files)
# 
# class ListingType(Enum):
#     directory = DIRECTORY_FLAG
#     file = FILE_FLAG
#     link = LINK_FLAG
#     other = ''
# 
# FTP_URL_TEMPLATE = 'ftp://{user}:{password}@{host}:{port}'
# 
# def download_ftp_url(source_url, target_uri, buffer_size=8192):
#     """Uses urllib. thread safe?"""
# 
#     ensure_file_directory(target_uri)
# 
#     with urllib.request.urlopen(source_url) as source_file:
#         with open(target_uri, 'wb') as target_file:
#             shutil.copyfileobj(source_file, target_file, buffer_size)


import io
import os
import tempfile
import unittest
from unittest import mock
from urllib.parse import urljoin
from foil.ftp import (parse_line, ftp_walk, ftp_listing_paths, ListingType,
                      FTP_URL_TEMPLATE, download_ftp_url)


def mock_directory_line(name):
    return 'drwxr-xr-x 4   ftsclient       ftsclient 60      Dec 11 10:03 {}'.format(name)


def mock_file_line(name):
    return '-rw-r--r-- 1   bd_mgr          online  3661980 Mar 30 02:13 {}'.format(name)


def mock_ftp_walk():
    return iter([('/root', ['directory1', 'directory2'], ['file1']),
                 ('/root/directory1', ['subdirectory'], []),
                 ('/root/directory1/subdirectory', [], ['file1', 'file2']),
                 ('/root/directory2', [], [])])


class MockFTPConnection:
    FTP_DIR_TREE = {
        '/root': [mock_directory_line('directory1'),
                  mock_directory_line('directory2'),
                  mock_file_line('file1')],
        '/root/directory1': [mock_directory_line('subdirectory')],
        '/root/directory1/subdirectory': [mock_file_line('file1'),
                                          mock_file_line('file2')],
        '/root/directory2': ['totals']}

    BINARY_DATA = {'file1': b'abc', 'file2': b'123'}

    def dir(self, path, callback):

# Path: foil/ftp.py
# def parse_line(line: str, char_index=0) -> Tuple[ListingType, str]:
#     """Parse FTP directory listing into (type, filename)."""
# 
#     entry_name = str.rpartition(line, ' ')[-1]
#     entry_type = LISTING_FLAG_MAP.get(line[char_index], ListingType.other)
#     return entry_type, entry_name
# 
# def ftp_walk(ftpconn: FTP, rootpath=''):
#     """Recursively traverse an ftp directory to discovery directory listing."""
# 
#     current_directory = rootpath
# 
#     try:
#         directories, files = directory_listing(ftpconn, current_directory)
#     except ftplib.error_perm:
#         return
# 
#     # Yield before recursion
#     yield current_directory, directories, files
# 
#     # Recurse into sub-directories
#     for name in directories:
#         new_path = os.path.join(current_directory, name)
# 
#         for entry in ftp_walk(ftpconn, rootpath=new_path):
#             yield entry
#     else:
#         return
# 
# def ftp_listing_paths(ftpconn: FTP, root: str) -> Iterable[str]:
#     """Generate the full file paths from a root path."""
# 
#     for current_path, dirs, files in ftp_walk(ftpconn, root):
#         yield from (os.path.join(current_path, file) for file in files)
# 
# class ListingType(Enum):
#     directory = DIRECTORY_FLAG
#     file = FILE_FLAG
#     link = LINK_FLAG
#     other = ''
# 
# FTP_URL_TEMPLATE = 'ftp://{user}:{password}@{host}:{port}'
# 
# def download_ftp_url(source_url, target_uri, buffer_size=8192):
#     """Uses urllib. thread safe?"""
# 
#     ensure_file_directory(target_uri)
# 
#     with urllib.request.urlopen(source_url) as source_file:
#         with open(target_uri, 'wb') as target_file:
#             shutil.copyfileobj(source_file, target_file, buffer_size)


# Path: tests/test_ftp.py
import io
import os
import tempfile
import unittest
from unittest import mock
from urllib.parse import urljoin
from foil.ftp import (parse_line, ftp_walk, ftp_listing_paths, ListingType,
                      FTP_URL_TEMPLATE, download_ftp_url)



def mock_directory_line(name):
    return 'drwxr-xr-x 4   ftsclient       ftsclient 60      Dec 11 10:03 {}'.format(name)


def mock_file_line(name):
    return '-rw-r--r-- 1   bd_mgr          online  3661980 Mar 30 02:13 {}'.format(name)


def mock_ftp_walk():
    return iter([('/root', ['directory1', 'directory2'], ['file1']),
                 ('/root/directory1', ['subdirectory'], []),
                 ('/root/directory1/subdirectory', [], ['file1', 'file2']),
                 ('/root/directory2', [], [])])


class MockFTPConnection:
    FTP_DIR_TREE = {
        '/root': [mock_directory_line('directory1'),
                  mock_directory_line('directory2'),
                  mock_file_line('file1')],
        '/root/directory1': [mock_directory_line('subdirectory')],
        '/root/directory1/subdirectory': [mock_file_line('file1'),
                                          mock_file_line('file2')],
        '/root/directory2': ['totals']}

    BINARY_DATA = {'file1': b'abc', 'file2': b'123'}

    def dir(self, path, callback):

        listings = self.FTP_DIR_TREE[path]