#!/usr/bin/env python
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


"""
Parallel test runner for GoogleTest programs.

This script allows one to execute GoogleTest tests in parallel.
GoogleTest programs come with built-in support for running in parallel.
Here tests can automatically be partitioned across a number of test
program invocations ("shards"). This script provides a convenient
wrapper around that functionality and stream-lined output.
"""


from __future__ import print_function

import multiprocessing
import optparse
import os
import shlex
import signal
import subprocess
import sys


DEFAULT_NUM_JOBS = int(multiprocessing.cpu_count() * 1.5)


class Bcolors(object):
    """
    A collection of tty output modifiers.

    To switch the output of a string, prefix it with the desired
    modifier, and terminate it with 'ENDC'.
    """

    HEADER = '\033[95m' if sys.stdout.isatty() else ''
    OKBLUE = '\033[94m' if sys.stdout.isatty() else ''
    OKGREEN = '\033[92m' if sys.stdout.isatty() else ''
    WARNING = '\033[93m' if sys.stdout.isatty() else ''
    FAIL = '\033[91m'if sys.stdout.isatty() else ''
    ENDC = '\033[0m' if sys.stdout.isatty() else ''
    BOLD = '\033[1m' if sys.stdout.isatty() else ''
    UNDERLINE = '\033[4m' if sys.stdout.isatty() else ''

    @staticmethod
    def colorize(string, *color_codes):
        """Decorate a string with a number of color codes."""
        colors = ''.join(color_codes)
        return '{begin}{string}{end}'.format(
            begin=colors if sys.stdout.isatty() else '',
            string=string,
            end=Bcolors.ENDC if sys.stdout.isatty() else '')


def run_test(opts):
    """
    Perform an actual run of the test executable.

    Expects a list of parameters giving the number of the current
    shard, the total number of shards, and the executable to run.
    """
    shard, nshards, executable = opts

    signal.signal(signal.SIGINT, signal.SIG_IGN)

    env = os.environ.copy()
    env['GTEST_TOTAL_SHARDS'] = str(nshards)
    env['GTEST_SHARD_INDEX'] = str(shard)

    try:
        output = subprocess.check_output(
            executable.split(),
            stderr=subprocess.STDOUT,
            env=env,
            universal_newlines=True)
        print(Bcolors.colorize('.', Bcolors.OKGREEN), end='')
        sys.stdout.flush()
        return True, output
    except subprocess.CalledProcessError as error:
        print(Bcolors.colorize('.', Bcolors.FAIL), end='')
        sys.stdout.flush()
        return False, error.output


def parse_arguments():
    """Return the executable to work on, and a list of options."""
    parser = optparse.OptionParser(
        usage='Usage: %prog [options] <test> [-- <test_options>]')

    parser.add_option(
        '-j', '--jobs', type='int',
        default=DEFAULT_NUM_JOBS,
        help='number of parallel jobs to spawn. DEFAULT: {default_}'
        .format(default_=DEFAULT_NUM_JOBS))

    parser.add_option(
        '-s', '--sequential', type='string',
        default='',
        help='gtest filter for tests to run sequentially')

    parser.add_option(
        '-v', '--verbosity', type='int',
        default=1,
        help='output verbosity:'
        ' 0 only shows summarized information,'
        ' 1 also shows full logs of failed shards, and anything'
        ' >1 shows all output. DEFAULT: 1')

    parser.epilog = (
        'The environment variable MESOS_GTEST_RUNNER_FLAGS '
        'can be used to set a default set of flags. Flags passed on the '
        'command line always have precedence over these defaults.')

    # If the environment variable `MESOS_GTEST_RUNNER_FLAGS` is set we
    # use it to set a default set of flags to pass. Flags passed on
    # the command line always have precedence over these defaults.
    #
    # We manually construct `args` here and make use of the fact that
    # in `optparser`'s implementation flags passed later on the
    # command line overrule identical flags passed earlier.
    args = []
    if 'MESOS_GTEST_RUNNER_FLAGS' in os.environ:
        args.extend(shlex.split(os.environ['MESOS_GTEST_RUNNER_FLAGS']))
    args.extend(sys.argv[1:])

    (options, executable) = parser.parse_args(args)

    if not executable:
        parser.print_usage()
        sys.exit(1)

    if not os.path.isfile(executable[0]):
        print(
            Bcolors.colorize(
                "ERROR: File '{file}' does not exists"
                .format(file=executable[0]), Bcolors.FAIL),
            file=sys.stderr)
        sys.exit(1)

    if not os.access(executable[0], os.X_OK):
        print(
            Bcolors.colorize(
                "ERROR: File '{file}' is not executable"
                .format(file=executable[0]), Bcolors.FAIL),
            file=sys.stderr)
        sys.exit(1)

    if options.sequential and options.sequential.count(':-'):
        print(
            Bcolors.colorize(
                "ERROR: Cannot use negative filters in "
                "'sequential' parameter: '{filter}'"
                .format(filter=options.sequential), Bcolors.FAIL),
            file=sys.stderr)
        sys.exit(1)

    if options.sequential and os.environ.get('GTEST_FILTER') and \
            os.environ['GTEST_FILTER'].count(':-'):
        print(
            Bcolors.colorize(
                "ERROR: Cannot specify both 'sequential' ""option "
                "and environment variable 'GTEST_FILTER' "
                "containing negative filters",
                Bcolors.FAIL),
            file=sys.stderr)
        sys.exit(1)

    # Since empty strings are falsy, directly compare against `None`
    # to preserve an empty string passed via `GTEST_FILTER`.
    if os.environ.get('GTEST_FILTER') != None:
        options.parallel = '{env_filter}:-{sequential_filter}'\
                         .format(env_filter=os.environ['GTEST_FILTER'],
                                 sequential_filter=options.sequential)
    else:
        options.parallel = '*:-{sequential_filter}'\
                         .format(sequential_filter=options.sequential)

    return executable, options


if __name__ == '__main__':
    EXECUTABLE, OPTIONS = parse_arguments()

    # TODO(ArmandGrillet): Remove this when we'll have switched to Python 3.
    dir_path = os.path.dirname(os.path.realpath(__file__))
    script_path = os.path.join(dir_path, 'check-python3.py')
    subprocess.call('python ' + script_path, shell=True, cwd=dir_path)

    def options_gen(executable, filter_, jobs):
        """Generator for options for a certain shard.

        Here we set up GoogleTest specific flags, and generate
        distinct shard indices.
        """
        opts = range(jobs)

        # If we run in a terminal, enable colored test output. We
        # still allow users to disable this themselves via extra args.
        if sys.stdout.isatty():
            args = executable[1:]
            executable = '{exe} --gtest_color=yes {args}'\
                         .format(exe=executable[0], args=args if args else '')

        if filter_:
            executable = '{exe} --gtest_filter={filter}'\
                         .format(exe=executable, filter=filter_)

        for opt in opts:
            yield opt, jobs, executable

    try:
        RESULTS = []

        POOL = multiprocessing.Pool(processes=OPTIONS.jobs)

        # Run parallel tests.
        #
        # Multiprocessing's `map` cannot properly handle `KeyboardInterrupt` in
        # some python versions. Use `map_async` with an explicit timeout
        # instead. See http://stackoverflow.com/a/1408476.
        RESULTS.extend(
            POOL.map_async(
                run_test,
                options_gen(
                    EXECUTABLE, OPTIONS.parallel, OPTIONS.jobs)).get(
                        timeout=sys.maxint))

        # Now run sequential tests.
        if OPTIONS.sequential:
            RESULTS.extend(
                POOL.map_async(
                    run_test,
                    options_gen(
                        EXECUTABLE, OPTIONS.sequential, 1)).get(
                            timeout=sys.maxint))

        # Count the number of failed shards and print results from
        # failed shards.
        #
        # NOTE: The `RESULTS` array stores the result for each
        # `run_test` invocation returning a tuple (success, output).
        NFAILED = len([success for success, __ in RESULTS if not success])

        # TODO(bbannier): Introduce a verbosity which prints results
        # as they arrive; this likely requires some output parsing to
        # ensure results from different tests do not interleave.
        for result in RESULTS:
            if not result[0]:
                if OPTIONS.verbosity > 0:
                    print(result[1], file=sys.stderr)
            else:
                if OPTIONS.verbosity > 1:
                    print(result[1], file=sys.stdout)

        if NFAILED > 0:
            print(Bcolors.colorize(
                '\n[FAIL]: {nfailed} shard(s) have failed tests'.format(
                    nfailed=NFAILED),
                Bcolors.FAIL, Bcolors.BOLD),
                  file=sys.stderr)
        else:
            print(Bcolors.colorize('\n[PASS]', Bcolors.OKGREEN, Bcolors.BOLD))

        sys.exit(NFAILED)

    except KeyboardInterrupt:
        # Force a newline after intermediate test reports.
        print()

        print('Caught KeyboardInterrupt, terminating workers')

        POOL.terminate()
        POOL.join()

        sys.exit(1)

    except OSError as error:
        print(Bcolors.colorize(
            '\nERROR: {err}'.format(err=error),
            Bcolors.FAIL, Bcolors.BOLD))

        POOL.terminate()
        POOL.join()

        sys.exit(1)
