#!/usr/bin/env python
""" Apply ordering to directories in base repo

Print out directory using some custom ordering
"""
from __future__ import print_function

import sys
from os import listdir
from os.path import (dirname, join as pjoin, abspath, isdir, isfile, basename)
from time import strptime, mktime, localtime

MY_PATH = dirname(__file__)
sys.path.append(abspath(MY_PATH))
from nobel_prize import (DEFAULT_PATH, COMMIT_MSG_FNAME, DATE_FMT, SNAPSHOT_RE,
                        read_info)
sys.path.append(abspath(pjoin(MY_PATH, '..', 'tools')))
from mytree import output_tree, get_parser as mt_get_parser, TreeMaker

# Directories will later be sorted by time, with latest first.  Set known
# directories to be at the top by giving them now + something times.
_now = mktime(localtime())
_known_dirs = ('repo', 'staging', 'working')
KNOWNS = dict(zip(_known_dirs, [_now + i for i in range(len(_known_dirs))]))


def msg_to_secs(msg_file):
    with open(msg_file, 'rt') as fobj:
        for line in fobj:
            if line.startswith('Date'):
                break
        else:
            return
    return mktime(strptime(line.strip(), DATE_FMT))


def sortkey_from_dir(path):
    base = basename(path)
    if base in KNOWNS:
        return KNOWNS[base]
    snap_match = SNAPSHOT_RE.match(base)
    if snap_match:
        return int(snap_match.groups()[0])
    msg_path = pjoin(path, COMMIT_MSG_FNAME)
    if isfile(msg_path):
        return msg_to_secs(msg_path)
    return base


def sortkey_from_file(path):
    base = basename(path)
    if base == COMMIT_MSG_FNAME:
        return 'zzz' + base
    return base


def dir_sort_func(path):
    files = []
    dirs = []
    for p in listdir(path):
        if p.startswith('.'):
            continue
        full_p = pjoin(path, p)
        if isdir(full_p):
            dirs.append(full_p)
        elif isfile(full_p):
            files.append(full_p)
    dirs = sorted(dirs, key=sortkey_from_dir)[::-1]
    files = sorted(files, key=sortkey_from_file)
    return dirs + files


class NpTreeMaker(TreeMaker):
    """ Adds nobel-prize-specific sorting function """

    def _default_sort_func(self, path):
        return dir_sort_func(path)


class LNpTreeMaker(NpTreeMaker):
    """ Adds nobel-prize specific directory labeling """

    def _default_label_func(self, path):
        path_str = super(NpTreeMaker, self)._default_label_func(path)
        if not isdir(path):
            return path_str
        msg_fname = pjoin(path, COMMIT_MSG_FNAME)
        if not isfile(msg_fname):
            return path_str
        info = read_info(msg_fname)
        return u'{:44s}"{}"'.format(path_str, info['notes'])


def main():
    parser = mt_get_parser()
    parser.add_argument('root_dir',
                        nargs='?',
                        default=DEFAULT_PATH,
                        help='directory for which to show tree repr')
    parser.add_argument('--label', action='store_true',
                        help='Whether to label directories with Notes')
    args = parser.parse_args()
    output_tree(args, klass=LNpTreeMaker if args.label else NpTreeMaker)


if __name__ == '__main__':
    main()
