#!/usr/bin/env python

# Copyright (C) 2016 The Android Open Source Project
#
# Licensed 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.

'''Main test suite execution script.'''
import argparse
import inspect
import logging
import os
import signal
import subprocess
import sys
import time
import collections
import xml.etree.ElementTree as ET

from config import Config
from tests.harness import util_constants
from tests.harness.exception import TestSuiteException, FailFastException
from tests.harness import UtilAndroid
from tests.harness import UtilBundle
from tests.harness import util_log
from tests.harness.util_functions import load_py_module
from tests.harness.decorators import deprecated

# For some reason pylint is not able to understand the class returned by
# from util_log.get_logger() and generates a lot of false warnings
#pylint: disable=maybe-no-member

EMU_PROC = None

def _parse_args():
    '''Parse the command line arguments.

    Returns:
        A namespace object that contains the options specified to run_tests on
        the command line.
    '''

    parser = argparse.ArgumentParser(description='Run the test suite.')

    parser.add_argument('--config', '-c',
                        metavar='path',
                        help='Path to a custom config file.')
    parser.add_argument('--device', '-d',
                        help='Specify the device id of the device to test on.')
    parser.add_argument('--test', '-t',
                        metavar='path',
                        help='Specify a specific test to run.')
    group = parser.add_mutually_exclusive_group()
    group.add_argument('--wimpy', '-w',
                        action='store_true',
                        default=None,
                        help='Test only a core subset of features.')
    group.add_argument('--app-types',
                        default=['java', 'cpp', 'jni'],
                        nargs='*',
                        help='Specify a list of Android app types against which'
                             ' to run the tests',
                        dest='bundle_types')
    parser.add_argument('--install-only',
                        action='store_true',
                        default=False,
                        help='It only runs the pre-run stage of the test suite.'
                             ' It installs the required APKs but does not '
                             'execute the tests.',
                        dest='install_only')
    parser.add_argument('--no-install', '-n',
                        action='store_true',
                        default=False,
                        help='Stop the test suite installing apks to device.',
                        dest='noinstall')
    parser.add_argument('--no-uninstall',
                        action='store_true',
                        default=False,
                        help='Stop the test suite uninstalling apks after '
                             'completion.',
                        dest='nouninstall')
    parser.add_argument('--print-to-stdout',
                        action='store_true',
                        default=False,
                        help='Print all logging information to standard out.',
                        dest='print_to_stdout')
    parser.add_argument('--verbose', '-v',
                        action='store_true',
                        default=None,
                        help='Store extra info in the log.')
    parser.add_argument('--fail-fast',
                        action='store_true',
                        default=False,
                        help='Exit the test suite immediately on the first failure.')
    parser.add_argument('--run-emu',
                        action='store_true',
                        default=None,
                        help='Spawn an emulator and run the test suite on that.'
                             ' Specify the emulator command line in the config'
                             ' file or with -emu-cmd.',
                        dest='run_emu')

    # Get the properties of the Config class and add a command line argument
    # for each.
    this_module = sys.modules[__name__]
    for member_name, member_obj in inspect.getmembers(Config):
        if (inspect.isdatadescriptor(member_obj) and
            member_name not in ['__weakref__', 'device', 'verbose']):

            # List type properties can take one or more arguments
            num_args = None
            if (isinstance(member_obj, property)
                and isinstance(member_obj.fget(Config), list)):
                num_args = '+'

            opt_name = member_name.replace('_', '-')

            setattr(this_module, opt_name, '')

            parser.add_argument('--' + opt_name,
                                nargs=num_args,
                                help=member_obj.__doc__,
                                dest=member_name)

    return parser.parse_args()


def _choice(first_choice, second_choice):
    '''Return first_choice if it is not None otherwise return second_choice.

    Args:
        first_choice: The first choice value.
        second_choice: The alternative value.

    Returns:
        The first argument if it is not None, and the second otherwise.
    '''
    return first_choice if first_choice else second_choice


class State(object):
    '''This class manages all objects required by the test suite.'''

    # pylint: disable=too-many-instance-attributes
    # Since this is a state class many attributes are expected.

    def __init__(self):
        '''State constructor.

        Raises:
            TestSuiteException: When unable to load config file.

            AssertionError: When assertions fail.
        '''

        # Parse the command line options
        args = _parse_args()

        # create a config instance
        if args.config:
            # use the user supplied
            config = State.load_user_configuration(args.config)
        else:
            # use the default configuration
            config = Config()

        # save the test denylist
        self.blocklist = _choice(args.blocklist, config.blocklist)

        # Allow any of the command line arguments to override the
        # values in the config file.
        self.adb_path = _choice(args.adb_path, config.adb_path)

        self.host_port = int(_choice(args.host_port, config.host_port))

        self.device = _choice(args.device, config.device)

        self.user_specified_device = self.device

        self.device_port = int(_choice(args.device_port, config.device_port))

        self.lldb_server_path_device = _choice(args.lldb_server_path_device,
                                               config.lldb_server_path_device)

        self.lldb_server_path_host = _choice(args.lldb_server_path_host,
                                             config.lldb_server_path_host)

        self.aosp_product_path = _choice(args.aosp_product_path,
                                         config.aosp_product_path)

        self.log_file_path = _choice(args.log_file_path, config.log_file_path)

        self.results_file_path = _choice(args.results_file_path,
                                         config.results_file_path)

        self.lldb_path = _choice(args.lldb_path, config.lldb_path)
        self.print_to_stdout = args.print_to_stdout
        self.verbose = _choice(args.verbose, config.verbose)
        self.timeout = int(_choice(args.timeout, config.timeout))
        self.emu_cmd = _choice(args.emu_cmd, config.emu_cmd)
        self.run_emu = args.run_emu
        self.wimpy = args.wimpy
        self.bundle_types = args.bundle_types if not self.wimpy else ['java']
        self.fail_fast = args.fail_fast

        # validate the param "verbose"
        if not isinstance(self.verbose, bool):
            raise TestSuiteException('The parameter "verbose" should be a '
                                     'boolean: {0}'.format(self.verbose))

        # create result array
        self.results = dict()
        self.single_test = args.test

        # initialise the logging facility
        log_level = logging.INFO if not self.verbose else logging.DEBUG
        util_log.initialise("driver",
                            print_to_stdout=self.print_to_stdout,
                            level=log_level,
                            file_mode='w', # open for write
                            file_path=self.log_file_path
                            )
        log = util_log.get_logger()

        if self.run_emu and not self.emu_cmd:
            log.TestSuiteException('Need to specify --emu-cmd (or specify a'
                ' value in the config file) if using --run-emu.')

        # create a results file
        self.results_file = open(self.results_file_path, 'w')

        # create an android helper object
        self.android = UtilAndroid(self.adb_path,
                                   self.lldb_server_path_device,
                                   self.device)
        assert self.android

        # create a test bundle
        self.bundle = UtilBundle(self.android,
                                 self.aosp_product_path)
        assert self.bundle

        # save the no pushing option
        assert isinstance(args.noinstall, bool)
        self.noinstall = args.noinstall

        assert isinstance(args.nouninstall, bool)
        self.nouninstall = args.nouninstall

        # install only option
        assert type(args.install_only) is bool
        self.install_only = args.install_only
        if self.install_only:
            log.log_and_print('Option --install-only set. The test APKs will '
                              'be installed on the device but the tests will '
                              'not be executed.')
            if self.noinstall:
                raise TestSuiteException('Conflicting options given: '
                                         '--install-only and --no-install')

        # TCP port modifier which is used to increment the port number used for
        # each test case to avoid collisions.
        self.port_mod = 0

        # total number of test files that have been executed
        self.test_count = 0

    def get_android(self):
        '''Return the android ADB helper instance.

        Returns:
            The android ADB helper, instance of UtilAndroid.
        '''
        assert self.android
        return self.android

    def get_bundle(self):
        '''Return the test executable bundle.

        Returns:
            The test exectable collection, instance of UtilBundle.
        '''
        return self.bundle

    def add_result(self, name, app_type, result):
        '''Add a test result to the collection.

        Args:
            name: String name of the test that has executed.
            app_type: type of app i.e. java, jni, or cpp
            result: String result of the test, "pass", "fail", "error".
        '''
        key = (name, app_type)
        assert key not in self.results
        self.results[key] = result

    def get_single_test(self):
        '''Get the name of the single test to run.

        Returns:
            A string that is the name of the python file containing the test to
            be run. If all tests are to be run this returns None.
        '''
        return self.single_test

    @staticmethod
    def load_user_configuration(path):
        '''Load the test suite config from the give path.

        Instantiate the Config class found in the module at the given path.
        If no suitable class is available, it raises a TestSuiteException.

        Args:
            path: String location of the module.

        Returns:
            an instance of the Config class, defined in the module.

        Raises:
            TestSuiteException: when unable to import the module or when a
                                subclass of Config is not found inside it.
        '''

        # load the module
        config_module = load_py_module(path)
        if not config_module:
            raise TestSuiteException('Unable to import the module from "%s"'
                                     % (path))

        # look for a subclass of Config
        for name, value in inspect.getmembers(config_module):
            if (inspect.isclass(value)
                and name != 'Config'
                and issubclass(value, Config)):
                # that's our candidate
                return value()

        # otherwise there are no valid candidates
        raise TestSuiteException('The provided user configuration is not '
                                 'valid. The module must define a subclass '
                                 'of Config')


def _kill_emulator():
    ''' Kill the emulator process. '''
    global EMU_PROC
    if EMU_PROC:
        try:
            EMU_PROC.terminate()
        except OSError:
            # can't kill a dead proc
            log = util_log.get_logger()
            log.debug('Trying to kill an emulator but it is already dead.')


def _check_emulator_terminated():
    ''' Throw an exception if the emulator process has ended.

    Raises:
        TestSuiteException: If the emulator process has ended.
    '''
    global EMU_PROC
    assert EMU_PROC
    if EMU_PROC.poll():
        stdout, stderr = EMU_PROC.communicate()
        raise TestSuiteException('The emulator terminated with output:'
            '\nstderr: {0}\nstdout: {1}.'.format(stderr, stdout))


@deprecated()
def _launch_emulator(state):
    '''Launch the emulator and wait for it to boot.

    Args:
        emu_cmd: The command line to run the emulator.

    Raises:
        TestSuiteException: If an emulator already exists or the emulator
                            process terminated before we could connect to it, or
                            we failed to copy lldb-server to the emulator.
    '''
    global EMU_PROC
    android = state.android
    if state.user_specified_device:
        if android.device_with_substring_exists(state.user_specified_device):
            raise TestSuiteException(
                'A device with name {0} already exists.',
                state.user_specified_device)
    else:
        if android.device_with_substring_exists('emulator'):
            raise TestSuiteException('An emulator already exists.')

    assert state.emu_cmd
    EMU_PROC = subprocess.Popen(state.emu_cmd.split(),
                                stdout=None,
                                stderr=subprocess.STDOUT)

    log = util_log.get_logger()
    log.info('Launching emulator with command line {0}'.format(state.emu_cmd))

    tries_number = 180
    tries = tries_number
    found_device = False
    while not found_device:
        try:
            android.validate_device(False, 'emulator')
            found_device = True
        except TestSuiteException as ex:
            tries -= 1
            if tries == 0:
                # Avoid infinitely looping if the emulator won't boot
                log.warning(
                    'Giving up trying to validate device after {0} tries.'
                    .format(tries_number))
                raise ex
            _check_emulator_terminated()
            # wait a bit and try again, maybe it has now booted
            time.sleep(10)

    tries = 500
    while not android.is_booted():
        tries -= 1
        if tries == 0:
            # Avoid infinitely looping if the emulator won't boot
            raise TestSuiteException('The emulator has failed to boot.')
        _check_emulator_terminated()
        time.sleep(5)

    # Need to be root before we can push lldb-server
    android.adb_root()
    android.wait_for_device()

    # Push the lldb-server executable to the device.
    output = android.adb('push {0} {1}'.format(state.lldb_server_path_host,
                                               state.lldb_server_path_device))

    if 'failed to copy' in output or 'No such file or directory' in output:
        raise TestSuiteException(
            'unable to push lldb-server to the emulator: {0}.'
            .format(output))

    output = android.shell('chmod a+x {0}'
                           .format(state.lldb_server_path_device))

    if 'No such file or directory' in output:
        raise TestSuiteException('Failed to copy lldb-server to the emulator.')


def _restart_emulator(state):
    '''Kill the emulator and start a new instance.

    Args:
        state: Test suite state collection, instance of State.
    '''
    _kill_emulator()
    _launch_emulator(state)


def _run_test(state, name, bundle_type):
    '''Execute a single test case.

    Args:
        state: Test suite state collection, instance of State.
        name: String file name of the test to execute.
        bundle_type: string for the installed app type (cpp|jni|java)

    Raises:
        AssertionError: When assertion fails.
    '''
    assert isinstance(name, str)

    try:
        state.android.check_adb_alive()
    except TestSuiteException as expt:
        global EMU_PROC
        if EMU_PROC:
            _restart_emulator(state)
        else:
            raise expt

    log = util_log.get_logger()
    sys.stdout.write('Running {0}\r'.format(name))
    sys.stdout.flush()
    log.info('Running {0}'.format(name))

    run_tests_dir = os.path.dirname(os.path.realpath(__file__))
    run_test_path = os.path.join(run_tests_dir, 'tests', 'run_test.py')

    # Forward port for lldb-server on the device to our host
    hport = int(state.host_port) + state.port_mod
    dport = int(state.device_port) + state.port_mod
    state.android.forward_port(hport, dport)
    state.port_mod += 1

    log.debug('Giving up control to {0}...'.format(name))

    params = map(str, [
        sys.executable,
        run_test_path,
        name,
        state.log_file_path,
        state.adb_path,
        state.lldb_server_path_device,
        state.aosp_product_path,
        dport,
        state.android.get_device_id(),
        state.print_to_stdout,
        state.verbose,
        state.wimpy,
        state.timeout,
        bundle_type
    ])

    return_code = subprocess.call(params)
    state.test_count += 1
    state.android.remove_port_forwarding()
    log.seek_to_end()

    # report in sys.stdout the result
    success = return_code == util_constants.RC_TEST_OK
    status_handlers = collections.defaultdict(lambda: ('error', log.error), (
            (util_constants.RC_TEST_OK, ('pass', log.info)),
            (util_constants.RC_TEST_TIMEOUT, ('timeout', log.error)),
            (util_constants.RC_TEST_IGNORED, ('ignored', log.info)),
            (util_constants.RC_TEST_FAIL, ('fail', log.critical))
        )
    )
    status_name, status_logger = status_handlers[return_code]
    log.info('Running %s: %s', name, status_name.upper())
    status_logger("Test %r: %s", name, status_name)

    # Special case for ignored tests - just return now
    if return_code == util_constants.RC_TEST_IGNORED:
        return

    state.add_result(name, bundle_type, status_name)

    if state.fail_fast and not success:
        raise FailFastException(name)

    # print a running total pass rate
    passes = sum(1 for key, value in state.results.items() if value == 'pass')
    log.info('Current pass rate: %s of %s executed.', passes, len(state.results))


def _check_lldbserver_exists(state):
    '''Check lldb-server exists on the target device and it is executable.

    Raises:
        TestSuiteError: If lldb-server does not exist on the target.
    '''
    assert state

    message = 'Unable to verify valid lldb-server on target'

    android = state.get_android()
    assert android

    cmd = state.lldb_server_path_device
    out = android.shell(cmd, False)
    if not isinstance(out, str):
        raise TestSuiteException(message)
    if out.find('Usage:') < 0:
        raise TestSuiteException(message)


def _suite_pre_run(state):
    '''This function is executed before the test cases are run (setup).

    Args:
        state: Test suite state collection, instance of State.

    Return:
        True if the pre_run step completes without error.
        Checks made:
            - Validating that adb exists and runs.
            - Validating that a device is attached.
            - We have root access to the device.
            - All test binaries were pushed to the device.
            - The port for lldb-server was forwarded correctly.

    Raises:
        AssertionError: When assertions fail.
    '''
    assert state
    log = util_log.get_logger()

    try:
        android = state.get_android()
        bundle = state.get_bundle()
        assert android
        assert bundle

        # validate ADB helper class
        android.validate_adb()
        log.log_and_print('Located ADB')

        if state.run_emu:
            log.log_and_print('Launching emulator...')
            _launch_emulator(state)
            log.log_and_print('Started emulator ' + android.device)
        else:
            android.validate_device()
            log.log_and_print('Located device ' + android.device)

        if state.noinstall and not state.single_test:
            bundle.check_apps_installed(state.wimpy)

        # elevate to root user
        android.adb_root()
        android.wait_for_device()
        # check that lldb-server exists on device
        android.kill_servers()
        _check_lldbserver_exists(state)

        if not state.noinstall:
            # push all tests to the device
            log.log_and_print('Pushing all tests...')
            bundle.push_all()
            log.log_and_print('Pushed all tests')
        log.log_and_print('Pre run complete')

    except TestSuiteException as expt:
        log.exception('Test suite pre run failure')

        # Even if we are logging the error, it may be helpful and more
        # immediate to find out the error into the terminal
        log.log_and_print('ERROR: Unable to set up the test suite: %s\n'
                          % expt.message, logging.ERROR)

        return False
    return True


def _suite_post_run(state):
    '''This function is executed after the test cases have run (teardown).

    Args:
        state: Test suite state collection, instance of State.
    Returns:
        Number of failures
    '''
    log = util_log.get_logger()

    if not state.noinstall and not state.nouninstall:
        if state.wimpy:
            state.bundle.uninstall_all_apk()
        else:
            state.bundle.uninstall_all()
        log.log_and_print('Uninstalled/Deleted all tests')

    total = 0
    passes = 0
    failures = 0

    results = ET.Element('testsuite')
    results.attrib['name'] = 'LLDB RS Test Suite'

    for key, value in state.results.items():
        total += 1
        if value == 'pass':
            passes += 1
        else:
            failures += 1

        # test case name, followed by pass, failure or error elements
        testcase = ET.Element('testcase')
        testcase.attrib['name'] = "%s:%s" % key
        result_element = ET.Element(value)
        result_element.text = "%s:%s" % key
        testcase.append(result_element)
        results.append(testcase)

    assert passes + failures == total, 'Invalid test results status'
    if failures:
        log.log_and_print(
            'The following failures occurred:\n%s\n' %
            '\n'.join('failed: %s:%s' % test_spec
                for test_spec, result in state.results.items() if result != 'pass'
        ))

    log.log_and_print('{0} of {1} passed'.format(passes, total))
    if total:
        log.log_and_print('{0}% rate'.format((passes*100)/total))

    results.attrib['tests'] = str(total)
    state.results_file.write(ET.tostring(results, encoding='iso-8859-1'))

    return failures


def _discover_tests(state):
    '''Discover all tests in the tests directory.

    Returns:
        List of strings, test file names from the 'tests' directory.
    '''
    tests = []

    single_test = state.get_single_test()
    if single_test is None:
        file_dir = os.path.dirname(os.path.realpath(__file__))
        tests_dir = os.path.join(file_dir, 'tests')

        for sub_dir in os.listdir(tests_dir):
            current_test_dir = os.path.join(tests_dir, sub_dir)
            if os.path.isdir(current_test_dir):
                dir_name = os.path.basename(current_test_dir)

                if dir_name == 'harness':
                    continue

                for item in os.listdir(current_test_dir):
                    if (item.startswith('test')
                        and item.endswith('.py')
                        and not item in state.blocklist):
                        tests.append(item)
    else:
        if single_test.endswith('.py'):
            tests.append(single_test)
        else:
            tests.append(single_test + '.py')

    return tests


def _deduce_python_path(state):
    '''Try to deduce the PYTHONPATH environment variable via the LLDB binary.

    Args:
        state: Test suite state collection, instance of State.

    Returns:
        True if PYTHONPATH has been updated, False otherwise.

    Raises:
        TestSuiteException: If lldb path provided in the config or command line
                            is incorrect.
        AssertionError: If an assertion fails.
    '''

    lldb_path = state.lldb_path
    if not lldb_path:
        # lldb may not be provided in preference of a manual $PYTHONPATH
        return False

    params = [lldb_path, '-P']

    try:
        proc = subprocess.Popen(params, stdout=subprocess.PIPE)
    except OSError as err:
        error_string = 'Could not run lldb at %s: %s' % (lldb_path, str(err))
        raise TestSuiteException(error_string)

    stdout = proc.communicate()[0]
    if stdout:
        os.environ['PYTHONPATH'] = stdout.strip()
        return True

    return False


def main():
    '''The lldb-renderscript test suite entry point.'''
    log = None

    try:
        # parse the command line
        state = State()
        assert state

        # logging is initialised in State()
        log = util_log.get_logger()

        # if we can, set PYTHONPATH for lldb bindings
        if not _deduce_python_path(state):
            log.log_and_print('Unable to deduce PYTHONPATH', logging.WARN)

        # pre run step
        if not _suite_pre_run(state):
            raise TestSuiteException('Test suite pre-run step failed')
        # discover all tests and execute them
        tests = _discover_tests(state)
        log.log_and_print('Found {0} tests'.format(len(tests)))
        if state.install_only:
            log.log_and_print('Test applications installed. Terminating due to '
                              '--install-only option')
        else:
            # run the tests
            for bundle_type in state.bundle_types:
                log.info("Running bundle type '%s'", bundle_type)
                for item in tests:
                    _run_test(state, item, bundle_type)
                # post run step
            quit(0 if _suite_post_run(state) == 0 else 1)

    except AssertionError:
        if log:
            log.exception('Internal test suite error')

        print('Internal test suite error')
        quit(1)

    except FailFastException:
        log.exception('Early exit after first test failure')
        quit(1)

    except TestSuiteException as error:
        if log:
            log.exception('Test suite exception')

        print('{0}'.format(str(error)))
        quit(2)

    finally:
        _kill_emulator()
        logging.shutdown()

def signal_handler(_, _unused):
    '''Signal handler for SIGINT, caused by the user typing Ctrl-C.'''
    # pylint: disable=unused-argument
    # pylint: disable=protected-access
    print('Ctrl+C!')
    os._exit(1)


# execution trampoline
if __name__ == '__main__':
    signal.signal(signal.SIGINT, signal_handler)
    main()
