#!/usr/bin/python

import os
import sys
import re
import subprocess


devnull = open(os.devnull, 'w')


def call(cmd):
    p = subprocess.Popen(cmd.split(),
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    out, err = p.communicate()
    return out.decode('utf-8'), err.decode('utf-8'), p.returncode


def execute(cmd, silent=False):
    if silent:
        params = {
                'stdout': devnull,
                'stderr': devnull,
                }
    else:
        params = {}

    retcode = subprocess.call(cmd.split(), **params)
    return retcode


def exists(cmd):
    return execute('which %s' % cmd, silent=True) == 0


def get_modified(ext):
    modified = re.compile('^(?:M|A).(?P<name>.*\.%s)' % ext)
    out, _, _ = call('git status --porcelain')
    modifieds = []
    for line in out.splitlines():
        match = modified.match(line.strip())
        if (match):
            modifieds.append(match.group('name'))
    return modifieds


def output(prg, out, err):
    print(' * %s:\n%s\n%s' % (prg, out, err))


def die(msg):
    print(msg)
    sys.exit(1)


def check_python():

    modifieds = get_modified('py')
    if not modifieds:
        return

    has_pep8 = exists('pep8')
    has_pylint = exists('pylint')
    has_pyflakes = exists('pyflakes')
    if not (has_pep8 or has_pylint or has_pyflakes):
        die('Install PEP8, PyLint and PyFlakes!')

    rrcode = 0
    for file in modifieds:
        if has_pep8:
            out, err, _ = call('pep8 %s' % file)
            if out or err:
                output('pep8', out, err)
                rrcode = rrcode | 1
        if has_pylint:
            retcode = execute('pylint -f parseable -E -d E0213,E1101,E1002,E1121,E0211,E0611,E0602,E1103 %s' % file)
            rrcode = retcode | rrcode
        if has_pyflakes:
            retcode = execute('pyflakes %s' % file)
            rrcode = retcode | rrcode

    if rrcode != 0:
        sys.exit(rrcode)


def check_javascript():

    modifieds = get_modified('js')
    if not modifieds:
        return

    has_jsl = exists('gjslint')
    if not has_jsl:
        die('Install Closure-Lint!')

    rrcode = 0
    for file in modifieds:
        out, err, retcode = call('gjslint --nojsdoc %s' % file)
        if out or err:
            output('gjslint', out, err)
            rrcode = rrcode | retcode

    if rrcode != 0:
        sys.exit(rrcode)


def main():
    check_python()
    check_javascript()


if __name__ == '__main__':
    main()
