#!/usr/bin/env python

from __future__ import print_function

import argparse
import subprocess
import sys


verbose = False


def call(*args, **kwargs):
    if verbose:
        print(' '.join(args[0]))
    ret = subprocess.call(*args, **kwargs)
    if ret != 0:
        sys.exit(ret)


def main(argv):
    parser = argparse.ArgumentParser(prog='run')
    parser.add_argument('-v', '--verbose', action='store_true')
    subps = parser.add_subparsers()

    subp = subps.add_parser('build', help='build the package')
    subp.set_defaults(func=run_build)

    subp = subps.add_parser('clean', help='Remove any local files.')
    subp.set_defaults(func=run_clean)

    subp = subps.add_parser('coverage',
                            help='Run tests and report code coverage.')
    subp.set_defaults(func=run_coverage)

    subp = subps.add_parser('format',
                            help='Reformat the source code.')
    subp.set_defaults(func=run_format)

    subp = subps.add_parser('help',
                            help='Get help on a subcommand.')
    subp.add_argument(nargs='?', action='store', dest='subcommand',
                      help='The command to get help for.')
    subp.set_defaults(func=run_help)

    subp = subps.add_parser('install',
                            help='build the package and install locally.')
    subp.set_defaults(func=run_install)
    subp.add_argument('--system', action='store_true',
                      help=('Install to the system site-package dir '
                            'rather than the user\'s (requires root).'))

    subp = subps.add_parser('lint',
                            help='run lint over the source')
    subp.set_defaults(func=run_lint)

    subp = subps.add_parser('tests',
                            help='run the tests')
    subp.set_defaults(func=run_tests)

    args = parser.parse_args(argv)

    global verbose
    if args.verbose:
        verbose = True
    args.func(args)


def run_build(args):
    del args
    call([sys.executable, 'setup.py', 'build', '--quiet'])


def run_clean(args):
    del args
    call(['git', 'clean', '-fxd'])


def run_coverage(args):
    del args
    call(['python', '-m', 'coverage', 'run', '-m', 'unittest',
          'discover', '-p', '*_test.py'])
    call(['python3', '-m', 'coverage', 'run', '--append', '-m', 'unittest',
          'discover', '-p', '*_test.py'])
    call([sys.executable, '-m', 'coverage', 'report', '--show-missing'])


def run_format(args):
    del args
    call('autopep8 --in-place *.py */*.py', shell=True)


def run_help(args):
    if args.subcommand:
        main([args.subcommand, '--help'])
    main(['--help'])


def run_install(args):
    if args.system:
        argv = []
    else:
        argv = ['--user']
    call([sys.executable, 'setup.py', 'install'] + argv)


def run_lint(args):
    del args
    call('pylint --rcfile=pylintrc */*.py', shell=True)


def run_tests(args):
    del args
    call([sys.executable, '-m', 'unittest', 'discover',
          '-p', '*_test.py'])


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))
