#!/usr/bin/env python
import argparse
import datetime
import jinja2
import logging
import os
import pprint
import re
import subprocess
import teamanalysis.config
import teamanalysis.git
import teamanalysis.repos
import teamanalysis.time
import webbrowser

LOGGER = logging.getLogger('overview-by-date')

def _get_abspath(repo):
    return '/Users/eliribble/src/teamanalysis/repos/{}/'.format(repo)

def _get_commit_count(repo, start, end, my_email):
    abspath = _get_abspath(repo)
    os.chdir(abspath)
    command = ['git', 'checkout', 'master']
    subprocess.check_output(command, stderr=subprocess.STDOUT)
    command = [
            'git',
            'log',
            '--pretty=format:"%h %aI %aE"',
            '--after={}'.format(start.isoformat()),
            '--before={}'.format(end.isoformat())]
    LOGGER.debug(" ".join(command))
    output = subprocess.check_output(command)
    lines = output.split('\n')
    total = len(lines) if output else 0
    my_lines = [line for line in lines if my_email in line]
    mine = len(my_lines)
    return {'total': total, 'mine': mine}

def _get_commit_sha_by_date(repo, timepoint):
    abspath = _get_abspath(repo)
    os.chdir(abspath)
    command = [
        'git',
        'rev-list',
        '-n',
        '1',
        '--before="{}"'.format(timepoint.date().isoformat()),
        'master',
        '--',
    ]
    LOGGER.debug("%s", ' '.join(command))
    output = subprocess.check_output(command)
    output = output.strip()
    LOGGER.debug("%s: %s", ' '.join(command), output)
    return output

def _git_checkout_by_date(repo, timepoint):
    abspath = _get_abspath(repo)
    commit = _get_commit_sha_by_date(repo, timepoint)
    os.chdir(abspath)
    command = [
        'git',
        'checkout',
        commit,
    ]
    try:
        output = subprocess.check_output(command, stderr=subprocess.STDOUT)
    except subprocess.CalledProcessError:
        LOGGER.warning("Failed to execute '%s' in %s", command, abspath)
        return ''
    LOGGER.debug("Checked out %s at %s", repo, timepoint.date().isoformat())
    return output

TEST_FUNCTION_PATTERN = re.compile(r'\s+<Function')
def _count_tests(repo):
    abspath = _get_abspath(repo)
    os.chdir(abspath)
    command = [
        os.path.join(abspath, 've', 'bin', 'python'),
        '/usr/local/bin/py.test',
        '--collect-only'
    ]
    LOGGER.debug(" ".join(command))
    try:
        output = subprocess.check_output(command, stderr=subprocess.STDOUT)
    except subprocess.CalledProcessError:
        LOGGER.info("Failed to call py.test for %s", repo)
        return 0
    count = 0
    for line in output.split('\n'):
        if TEST_FUNCTION_PATTERN.match(line):
            count += 1
    LOGGER.debug("Counted %d tests for %s", count, repo)
    return count

def _get_test_count(repo, end):
    abspath = _get_abspath(repo)
    _git_checkout_by_date(repo, end)
    return _count_tests(repo)

def _show_summary(timepoint, my_email):
    start, end = teamanalysis.time.get_checkpoint(timepoint)
    LOGGER.debug("Working %s to %s for %s", start, end, timepoint)
    results = {}
    for repo in teamanalysis.repos.REPOSITORIES:
        commits = _get_commit_count(repo, start, end, my_email)
        tests = _get_test_count(repo, end)
        results[repo] = {
            'commits'   : commits,
            'tests'     : tests,
        }
        #print("{0:<30}: {1}".format(repo, results[repo]))
    #pprint.pprint({k: v['tests'] for k, v in results.items()})
    #pprint.pprint({k: v['commits'] for k, v in results.items()})
    totals = {
        'all_commits'   : sum([result['commits']['total'] for result in results.values()]),
        'my_commits'    : sum([result['commits']['mine'] for result in results.values()]),
        'tests'         : sum([result['tests'] for result in results.values() if result['tests']]),
    }
    print("\t".join(map(str, [start.date().isoformat(), end.date().isoformat(), totals['all_commits'], totals['my_commits'], totals['tests']])))

def main():
    logging.basicConfig()
    LOGGER.setLevel(logging.INFO)
    #LOGGER.setLevel(logging.DEBUG)

    config = teamanalysis.config.get()
    timepoint = datetime.datetime(2013, 12, 30, 0, 0, 1)
    now = datetime.datetime.utcnow()
    while timepoint < now + datetime.timedelta(days=7):
        _show_summary(timepoint, config['my_email'])
        timepoint = timepoint + datetime.timedelta(days=7)

if __name__ == '__main__':
    main()