#!/usr/bin/env python

import collections
import optparse
import os
import os.path
import shutil
import subprocess
import sys

def __backport_check_output():
    def check_output(*popenargs, **kwargs):
        r"""Run command with arguments and return its output as a byte string.

        Backported from Python 2.7 as it's implemented as pure python on stdlib.

        >>> check_output(['/usr/bin/python', '--version'])
        Python 2.6.2
        """
        process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
        output, unused_err = process.communicate()
        retcode = process.poll()
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
            error = subprocess.CalledProcessError(retcode, cmd)
            error.output = output
            raise error
        return output

    if not hasattr(subprocess, 'check_output'):
        setattr(subprocess, 'check_output', check_output)

__backport_check_output()
del __backport_check_output


FILE_LIST = 'git ls-files | egrep "\.%s$"'

ALL_FILES = FILE_LIST % '(php|sql|py|js|htm|c|cpp|h|sh|css)'
JS_FILES = FILE_LIST % 'js'
PY_FILES = FILE_LIST % 'py'
CPP_FILES = FILE_LIST % '(cc|cpp|h)'
C_FILES = FILE_LIST % '(c|h)'
C_LIKE_FILES = FILE_LIST % '(c|cc|cpp|h)'
HEADER_FILES = FILE_LIST % 'h'

RED = '\033[41m'
GREEN = '\033[42m'
NORMAL = '\033[0m'
COLS = int(subprocess.check_output(['tput', 'cols']))

Test = collections.namedtuple('Test', ['command', 'name', 'nonzero', 'config'])

TESTS = [
    Test(
        "%s | xargs pyflakes" % PY_FILES,
        'Py    - Pyflakes',
        False, 'testpyflakes',
    ),
    Test(
        "%s | xargs grep 'import\sipdb'" % PY_FILES,
        'Py    - ipdb',
        True, 'testipdb',
    ),
    Test(
        "%s | grep 'tests' | grep -v '_test.py$' | grep -v '__init__.py' | grep -v '/conftest.py'" % PY_FILES,
        'Py    - Test files should end in _test.py',
        True, 'testtestnames',
    ),
    Test(
        "%s | xargs egrep 'split\(.\\\\n.\)'" % PY_FILES,
        'Py    - Use s.splitlines over s.split',
        True, 'testsplitlines',
    ),
    Test(
        "%s | xargs grep -H -n -P '\t'" % ALL_FILES,
        "All   - No tabs",
        True, 'testtabs',
    ),
    Test(
        "make test",
        "Py    - Tests",
        False, 'testtests',
    ),
]

def get_git_config(config_name):
    config_result = ''
    try:
        config_result = subprocess.check_output([
            'git', 'config', config_name
        ])
    except subprocess.CalledProcessError: pass

    return config_result.strip()

def get_pre_commit_path():
    git_top = subprocess.check_output(
        ['git', 'rev-parse', '--show-toplevel']
    ).strip()
    return os.path.join(git_top, '.git/hooks/pre-commit')

class FixAllBase(object):
    name = None
    matching_files_command = None

    def get_all_files(self):
        try:
            files = subprocess.check_output(
                self.matching_files_command,
                shell=True,
            )
            files_split = files.splitlines()
            return [file.strip() for file in files_split]
        except subprocess.CalledProcessError:
            return []

    def fix_file(self, file):
        '''Implement to fix the file.'''
        raise NotImplementedError

    def run(self):
        '''Runs the process to fix the files. Returns True if nothign to fix.'''
        print '%s...' % self.name
        all_files = self.get_all_files()
        for file in all_files:
            print 'Fixing %s' % file
            self.fix_file(file)
        return not all_files

class FixTrailingWhitespace(FixAllBase):
    name = 'Trimming trailing whitespace'
    matching_files_command = '%s | xargs egrep -l "[[:space:]]$"' % ALL_FILES

    def fix_file(self, file):
        subprocess.check_call(['sed', '-i', '-e', 's/[[:space:]]*$//', file])

class FixLineEndings(FixAllBase):
    name = 'Fixing line endings'
    matching_files_command = "%s | xargs egrep -l $'\\r'\\$" % ALL_FILES

    def fix_file(self, file):
        subprocess.check_call(['dos2unix', file])
        subprocess.check_call(['mac2unix', file])

FIXERS = [
    FixTrailingWhitespace,
    FixLineEndings,
]

def run_tests():
    passed = True
    for test in TESTS:
        run_test = get_git_config('hooks.%s' % test.config)
        if run_test == 'false':
            print 'Skipping "%s" due to git config.' % test.name
            continue

        try:
            retcode = 0
            output = subprocess.check_output(
                test.command, shell=True, stderr=subprocess.STDOUT
            )
        except subprocess.CalledProcessError as e:
            retcode = e.returncode
            output = e.output

        pass_fail = '%sSuccess%s' % (GREEN, NORMAL)
        failed_test = False
        if (retcode and not test.nonzero) or (not retcode and test.nonzero):
            pass_fail = '%sFailure(%s)%s' % (RED, retcode, NORMAL)
            failed_test = True

        dots = COLS - len(pass_fail) - len(test.name)
        print '%s%s%s' % (test.name, '.' * dots, pass_fail)

        if failed_test:
            print
            print output
            passed = False

    return passed

if __name__ == '__main__':
    parser = optparse.OptionParser()
    parser.add_option(
        '-u', '--uninstall',
        action='store_true', dest='uninstall', default=False,
        help='Uninstall pre-commit script.'
    )
    parser.add_option(
        '-i', '--install',
        action='store_true', dest='install', default=False,
        help='Install pre-commit script.'
    )
    opts, args = parser.parse_args()

    if opts.install:
        pre_commit_path = get_pre_commit_path()
        shutil.copyfile(__file__, pre_commit_path)
        os.chmod(pre_commit_path, 0755)
        print 'Installed pre commit to %s' % pre_commit_path
        sys.exit(0)
    elif opts.uninstall:
        pre_commit_path = get_pre_commit_path()
        if os.path.exists(pre_commit_path):
            os.remove(pre_commit_path)
        print 'Removed pre-commit scripts.'

    passed = True
    for fixer in FIXERS:
        passed &= fixer().run()
    passed &= run_tests()

    if not passed:
        print '%sFailures / Fixes detected.%s' % (RED, NORMAL)
        print 'Please fix and commit again.'
        print "You could also pass --no-verify, but you probably shouldn't."
        print
        print "Here's git status for convenience: "
        print
        os.system('git status')
        sys.exit(-1)
