#!/usr/bin/env python

import os
import sys
import argparse
from pprint import pprint
from collections import OrderedDict

parser = argparse.ArgumentParser(description="Repositories watcher version 0.1.0")
parser.add_argument('-p', '--pull',    action='store_const', dest='pull',    const='pull', default='fetch',    help='pull instead of fetch')
parser.add_argument('-f', '--force',   action='store_const', dest='force',   const=True,   default=False,      help='force fetch/pull')
parser.add_argument('-v', '--verbose', action='store_const', dest='verbose', const='',     default=' --quiet', help='be verbose')
parser.add_argument('-V', '--version', action='version', version='%(prog)s 0.1.0')
parser.add_argument('directory', nargs='?', action='store', type=str, default=os.getcwd(), help='directory to start from')

ARGS = parser.parse_args()

skips = (
    'On branch',
    'HEAD detached',
    'Your branch is up-to-date',
    'nothing to commit, working directory clean',
)
fetches = (
    'Your branch is ahead',
    'Your branch is behind',
)

def check(dir):
    os.chdir(dir)
    status = check_status()
    if status is None and not ARGS.force:
        return
    if ARGS.force or status.startswith(fetches):
        os.system('git ' + ARGS.pull + ARGS.verbose)
        status = check_status()
        if status is None:
            return
    return status

def check_status():
    status = None
    for line in os.popen('git status').readlines():
        status = line.strip()
        if status and not status.startswith(skips):
            return status.strip('.,:')
    return None

endcolors = '\033[0m'
termcolors = {
    'blue':     '\033[94m',
    'yellow':   '\033[93m',
    'green':    '\033[92m',
    'end':      '\033[0m',
}

windmill = ['-', '\\', '|', '/']

def colored(str, color, apply = None):
    if apply is None:
        apply = sys.stdout.isatty()
    if apply:
        return termcolors[color] + str + endcolors
    return str

def tprint(str):
    if sys.stdout.isatty():
        print(str),

def main():
    prev = 'Finding gits... '
    tprint(prev)
    sys.stdout.flush()
    raws = os.popen('find . -name .git').readlines()
    dirs = sorted(raws)
    stats = OrderedDict()
    no = 0
    for dir in dirs:
        dir = ARGS.directory + '/' + dir[2:-6]
        msg = windmill[no % 4] + ' ' + dir
        tprint('\b' * 300)
        tprint(msg.ljust(len(prev)))
        prev = msg
        no += 1
        status = check(dir)
        if status:
            stats[dir] = status
    tprint('\r')
    tprint(''.ljust(len(prev))) # cleans string with spaces
    tprint('\b' * 300)
    tprint('\r')
    max = 1
    for dir in stats:
        if len(dir)>max:
            max = len(dir)
    for dir in stats:
        print("{dir} - {status}".format(status=colored(stats[dir], 'yellow'), dir=dir.ljust(max)))

if __name__ == '__main__':
    main()
