#!/usr/bin/env python3

import os
import re

from datetime import datetime
from optparse import OptionParser
from os import path


def add(arr):
    return arr[0] + arr[1]


assert add([1, 2]) == 3


def mul(arr):
    return arr[0] * arr[1]


assert mul([2, 3]) == 6


def echo(arg):
    print(arg)
    return arg


def compose(*funcs):
    return lambda arg=None: reduce(lambda val, func: func(val), funcs, arg)


test_compose = compose(lambda _: [2, 3], mul, lambda x: [x, 3], mul, lambda \
        x \
    : \
        [x, 1], add)
# 2 * 3 = 6 * 3 = 18 + 1 = 19
assert test_compose() == 19

date_reg_ex = re.compile("\d{4}-\d{2}-\d{2}_")
doesnt_start_with_date = lambda string: \
        date_reg_ex.search(string, 0, 11) is None
assert doesnt_start_with_date("1234-56-78_") == False
assert doesnt_start_with_date("a1234-56-78_")
assert doesnt_start_with_date("1234-56-78")
assert \
    doesnt_start_with_date("1234-56-78_ sdfsakdsdf fjalsdjhfaskj  ldfh") == False


def prop(key):
    def obj(dic):
        return dic[key]

    return obj


assert prop('key')({'key': 1}) == 1


def path_join(directory):
    def do_join(file_name):
        return path.join(directory, file_name)

    return do_join


def mk_dir_map(ret, directory):
    is_file = compose(path_join(directory), path.isfile)
    files = filter(is_file, os.listdir(directory))
    not_with_date = filter(doesnt_start_with_date, files)
    ret[directory] = map(lambda x: {'original': x}, not_with_date)
    return ret


def add_date(ret, directory):
    original = prop('original')
    add_dir_name = path_join(directory)

    def list_date(file_obj):
        date_from_obj = compose(original, add_dir_name, path.getctime, datetime.fromtimestamp)
        date = date_from_obj(file_obj)
        file_obj[
            'new'
        ] = date.strftime('%Y-%m-%d_{0}'.format(original(file_obj)))
        return file_obj

    ret[directory] = map(list_date, ret[directory])
    return ret


def rename(ret, directory):
    original = compose(prop('original'), path_join(directory))
    new = compose(prop('new'), path_join(directory))

    def do_rename(file_obj):
        os.rename(original(file_obj), new(file_obj))
        return echo("mv -v {0} {1}".format(original(file_obj), new(file_obj)))

    map(do_rename, ret[directory])
    return ret


def main(options, directories):
    real_directories = filter(path.isdir, directories)
    file_tree = reduce(mk_dir_map, real_directories, {})
    file_tree = reduce(add_date, file_tree, file_tree)
    file_tree = reduce(rename, file_tree, file_tree)


if __name__ == '__main__':
    parser = OptionParser()
    parser.add_option("-f", "--file", dest="filename", help="write report to FILE", metavar="FILE")
    parser.add_option("-q", "--quiet", action="store_false", dest="verbose", default=True, help="don't print status messages to stdout")

    options, args = parser.parse_args()
    main(options, args)