import sys
import re
import time
import pprint
import os.path

from collections import defaultdict

from checkmate.management.helpers import analyze_string,aggregate_statistics,get_files_list
from checkmate.settings import analyzers,aggregators

from checkmate.lib.frontends.git import GitProject,GitSnapshot,GitFileRevision

from blitzdb import FileBackend

if __name__ == '__main__':
    path = os.path.abspath(sys.argv[1])

    backend = FileBackend(path+"/.checkmate")
    backend.create_index(GitProject,'path')
    backend.create_index(GitSnapshot,'sha')
    backend.create_index(GitFileRevision,'sha')
    backend.create_index(GitFileRevision,'path')

    print "Git projects:",len(backend.filter(GitProject,{}))

    project = GitProject({'path':path,'pk':path})
    project.save(backend)

    print "Press [ENTER] to continue"
    sys.stdin.readline()

    if True:
        snapshots = project.get_snapshots()

        file_revisions_in_snapshot = {}
        last_snapshot = None
        for snapshot in snapshots:

            print "\n\n\n",snapshot.log,snapshot.committer_date
            if last_snapshot:
                diffs = last_snapshot.get_diffs(snapshot)
            else:
                diffs = snapshot.get_diffs(None)

            file_revisions = snapshot.get_file_revisions()

            deleted_files = [d[1] for d in diffs if d[0] == 'D']
            modified_file_revisions = [fr for fr in file_revisions if fr.path in [d[1] for d in diffs if d[0] == 'M']]
            added_file_revisions = [fr for fr in file_revisions if fr.path in [d[1] for d in diffs if d[0] == 'A']]

            print "%d files added, %d files modified, %d files deleted." % (len(added_file_revisions),len(modified_file_revisions),len(deleted_files))

            for path in deleted_files:
                if path in file_revisions_in_snapshot:
                    del file_revisions_in_snapshot[path]

            last_snapshot = snapshot

            backend.filter(GitFileRevision,{'snapshot' : snapshot}).delete()

            for file_revision in modified_file_revisions+added_file_revisions:
                print "Analyzing %s" % file_revision.path

                if file_revision.path in file_revisions_in_snapshot:
                    del file_revisions_in_snapshot[file_revision.path]

                try:
                    file_stats,file_issues = analyze_string(file_revision.get_file_content(),file_revision.path,analyzers)
                    if file_stats or file_issues:
                        file_revision.issues = file_issues
                        file_revision.stats = file_stats
                        file_revision.save(backend)
                        file_revisions_in_snapshot[file_revision.path] = file_revision
                except IOError:
                    pass

            snapshot.file_revisions = file_revisions_in_snapshot.items()
            snapshot.save(backend)
    
    print "Snapshots:",len(backend.filter(GitSnapshot,{}))
    print "File revisions:",len(backend.filter(GitFileRevision,{}))

    start = time.time()

    latest_snapshot = sorted(backend.filter(GitSnapshot,{}),key = lambda x:-x.committer_date_ts)[0]

    print latest_snapshot.log

    for path,file_revision in latest_snapshot.file_revisions:
        if file_revision.issues['metrics']:
            print file_revision.path
            print file_revision.issues['metrics']

        try:
            max_complexity = max([int(x) for x in file_revision.stats['metrics']['functions']['cyclomatic_complexity_distribution'].keys()])
        except:
            max_complexity = 0
        average_complexity = file_revision.stats['metrics']['functions']['average_cyclomatic_complexity'] 
        number_of_issues = len(file_revision.issues['metrics'])
        print "%.2f\t%.4d\t%d\t%s" % (average_complexity,max_complexity,number_of_issues,file_revision.snapshot.committer_date)

    print time.time()-start

    exit(0)
