#!/usr/bin/env python

from __future__ import print_function

import argparse
import os
import subprocess
import sys

from tools import cov


verbose = False

repo_dir = os.path.abspath(os.path.dirname(__file__))
path_to_cov = os.path.join(repo_dir, 'tools', 'cov.py')
path_to_runner = os.path.join(repo_dir, 'typ', 'runner.py')


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('clean', help='Remove any local files.')
    subp.set_defaults(func=run_clean)

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

    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('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_clean(args):
    call(['git', 'clean', '-fxd'])


def run_coverage(args):
    if not args.path:
        args.path = [repo_dir]
    if not args.source:
        args.source = [os.path.join(repo_dir, 'typ')]
    argv = cov.argv_from_args(args)
    cov_args = [path_to_runner, '-j', '1']
    python = sys.executable
    call([python, path_to_cov] + argv + cov_args)


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


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


def run_tests(args):
    python = sys.executable
    # Test running the typ module directly if it is in sys.path.
    call([python, '-m', 'typ', 'typ.tests.main_test.TestMain.test_basic'])

    # Testing running the runner directly if nothing is in sys.path.'
    home_dir = os.environ['HOME']
    call([python, path_to_runner, 'typ.tests.main_test.TestMain.test_basic'],
         cwd=home_dir)

    # Run the remaining tests.
    call([python, path_to_runner])


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