#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import print_function
from subprocess import call
import argparse
import glob
import logging
import os
import sys


def find_tests():
    tests = []

    for test in glob.glob("*.t") + glob.glob("*.t.exe"):
        if os.access(test, os.X_OK):
            # Executables only
            tests.append(test)
        else:
            log.debug("Ignored test %s as it is not executable", test)

    log.info("Tests found: %s", len(tests))

    return tests


def run_test(test):
    log.warn("Running test %s %s times", test, cmd_args.repeat)

    if not test.startswith(".{0}".format(os.path.sep)):
        test = ".{0}{1}".format(os.path.sep, test)

    for i in range(cmd_args.repeat):
        exit = call([test], stdout=sys.stdout, stderr=sys.stderr)

        if exit != 0:
            log.error("Failed to run test %s on repetition %s", test, i)
            break


def parse_args():
    parser = argparse.ArgumentParser(description="Run Taskwarrior tests repeatedly")
    parser.add_argument('--logging', '-l', action="count", default=0,
                        help="Logging level. -lll is the highest level")
    parser.add_argument('--repeat', metavar="N", type=int, default=100,
                        help="How many times to run each test (default: 100)")
    parser.add_argument('--noprompt', action="store_true",
                        help="Do not prompt when running all tests")
    parser.add_argument('test', nargs="*",
                        help="Test files to run repeatedly. Unspecified = all tests")
    return parser.parse_args()


def main():
    if cmd_args.test:
        for test in cmd_args.test:
            run_test(test)
    else:
        if not cmd_args.noprompt:
            r = raw_input("No test was specified, are you sure you want to run all tests? (y/N)\n")
            if not (r and r[0] in ["y", "Y"]):
                return

        log.info("Stress testing all tests")
        for test in find_tests():
            run_test(test)


if __name__ == "__main__":
    cmd_args = parse_args()

    if cmd_args.logging == 1:
        level = logging.WARN
    elif cmd_args.logging == 2:
        level = logging.INFO
    elif cmd_args.logging >= 3:
        level = logging.DEBUG
    else:
        level = logging.ERROR

    logging.basicConfig(
        format="%(asctime)s - %(levelname)s - %(message)s",
        level=level,
    )
    log = logging.getLogger(__name__)

    log.debug("Parsed commandline arguments: %s", cmd_args)

    try:
        main()
    except Exception as e:
        log.exception(e)
        sys.exit(1)
