#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import (
    absolute_import, division, print_function, unicode_literals
)
from nine import (
    IS_PYTHON2, basestring, chr, class_types, filter, integer_types,
    implements_iterator, implements_to_string, implements_repr,
    input, iterkeys, iteritems, itervalues, long, map,
    native_str, nine, nimport, range, range_list, reraise, str, zip
)

argparse = nimport('argparse')
os = nimport('os')
subprocess = nimport('subprocess')
time = nimport('time')


def run():
    """Runs this program.

    The program runs 'rsync' to copy files from one directory tree to another
    """
    start_time = time.time()
    options = parse_cmd_line()
    rsync_dir(
        src_dir=options['srcdir'],
        dest_dir=options['destdir'],
        remove=options['remove'],
        verbose=options['verbose'])
    if options['verbose']:
        print('Done, in {} seconds!'.format(time.time() - start_time))


def parse_cmd_line():
    """Parses the command-line arguments.

    Arguments:
        None

    Returns:
        A dictionary with each of the supplied command-line arguments.
    """
    parser = argparse.ArgumentParser(
        description=' '.join([
            'Uses rsync to recursively copy files from a source directory',
            'to a destination directory']))
    parser.add_argument(
        'srcdir',
        help='specify the directory that files will be recursively copied from')
    parser.add_argument(
        'destdir',
        help='specify the directory that files will be recursively copied to')
    parser.add_argument(
        '--remove', '-r',
        action='store_true',
        default=False,
        help=' '.join([
            'specify this to remove files from the destination directory that',
            'no longer exist under the source directory']))
    parser.add_argument(
        '--verbose', '-v',
        action='store_true',
        default=False,
        help='specify this to display verbose output')
    # vars() turns Namespace into a regular dictionary
    options = vars(parser.parse_args())
    options['srcdir'] = chomp_sep(options['srcdir'])
    options['destdir'] = chomp_sep(options['destdir'])
    return options


def chomp_sep(dir_name):
    """Removes any trailing directory separator characters from the given
    directory name.

    Arguments:
        dir_name: the name that has to have any trailing slashes removed

    Returns:
        The directory name with no trailing separator characters
    """
    while dir_name.endswith(os.sep):
        dir_name = dir_name[:-1]
    return dir_name


def rsync_dir(**kwargs):
    """Copies files from one directory tree to another.

    Arguments:
        kwargs: a dictionary with the following keys:-
            src_dir:    the directory from which to recursively copy files
            dest_dir:   the directory into which files are recursively copied
            remove:     whether to remove files that exist in the
                        dest_dir directory but not the src_dir directory
            verbose:    whether to output text describing non-fatal events

    Returns:
        None
    """
    src_dir = kwargs.pop('src_dir')
    dest_dir = kwargs.pop('dest_dir')
    remove = kwargs.pop('remove')
    verbose = kwargs.pop('verbose')
    if kwargs:
        raise TypeError('Unexpected **kwargs: %r' % kwargs)
    rsync_options = [
        '--archive',
        '--compress',
        '--partial']
    if remove:
       rsync_options.append('--delete')
    if verbose:
        rsync_options.extend(['--progress', '--human-readable', '--stats'])
    else:
        rsync_options.append('--quiet')
    subprocess.call(
        'sudo rsync {} "{}/" "{}"'.format(
            ' '.join(rsync_options),
            src_dir,
            dest_dir),
        shell=True)
    if verbose:
        print('Performed apt-clone clone from {} to {}'.format(
            src_dir,
            dest_dir))


if __name__ == '__main__':
    run()
