#!/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')
fnmatch = nimport('fnmatch')
os = nimport('os')
sys = nimport('sys')
time = nimport('time')


def run():
    """Runs this program.

    The program removes unneeded files from a directory.
    """
    start_time = time.time()
    options = parse_cmd_line()
    rm_unneeded_files(options['directory'], 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([
            'Removes any unneeded files found',
            'in the given directory or any subdirectory']))
    parser.add_argument(
        'directory',
        help='specify the directory containing unneccessary files')
    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['directory'] = chomp_sep(options['directory']) + os.sep
    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 rm_unneeded_files(dir_name, verbose):
    """Removes unneeded files under directory dir_name.

    Arguments:
        dir_name:   the root directory under which to search for
                    unneccessary files to delete
        verbose:    whether to output text describing non-fatal events

    Returns:
        None
    """
    _fnmatch = fnmatch.fnmatch
    for tupl in os.walk(dir_name):
        dir_name = tupl[0]  # (dir, subdirs, filenames)
        for fname in tupl[2]:
            if (_fnmatch(fname, '*~')
                or _fnmatch(fname, '*.#')
                or _fnmatch(fname, '#*#')
                or _fnmatch(fname, '*.sw?')
                or _fnmatch(fname, '*.autosave')
                or _fnmatch(fname, '*.DS_Store')
                or _fnmatch(fname, '*.lein_failures')
                or _fnmatch(fname, '*.lein-repl-history')
                or _fnmatch(fname, '*.lisp-temp')
            ):
                dir_fname = os.path.join(dir_name, fname)
                try:
                    os.remove(dir_fname)
                    if verbose:
                        print("Removed: '{}'".format(dir_fname))
                except OSError as err:
                        print(
                            "Unable to remove: '{}' => {}".format(
                                dir_fname,
                                err),
                             file=sys.stderr)


if __name__ == '__main__':
    run()
