# Copyright 2016 Google Inc.
#
# 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.

from __future__ import print_function
from future import standard_library
standard_library.install_aliases()

import argparse
import contextlib
import inspect
import logging
import os
import sys

from mobly import base_test
from mobly import config_parser
from mobly import logger
from mobly import records
from mobly import signals
from mobly import utils


class Error(Exception):
    pass


def main(argv=None):
    """Execute the test class in a test module.

    This is the default entry point for running a test script file directly.
    In this case, only one test class in a test script is allowed.

    To make your test script executable, add the following to your file:

    .. code-block:: python

        from mobly import test_runner
        ...
        if __name__ == '__main__':
            test_runner.main()

    If you want to implement your own cli entry point, you could use function
    execute_one_test_class(test_class, test_config, test_identifier)

    Args:
        argv: A list that is then parsed as cli args. If None, defaults to cli
            input.
    """
    args = parse_mobly_cli_args(argv)
    # Find the test class in the test script.
    test_class = _find_test_class()
    if args.list_tests:
        _print_test_names(test_class)
        sys.exit(0)
    # Load test config file.
    test_configs = config_parser.load_test_config_file(args.config[0],
                                                       args.test_bed)
    # Parse test specifiers if exist.
    tests = None
    if args.tests:
        tests = args.tests
    # Execute the test class with configs.
    ok = True
    for config in test_configs:
        runner = TestRunner(log_dir=config.log_path,
                            test_bed_name=config.test_bed_name)
        with runner.mobly_logger():
            runner.add_test_class(config, test_class, tests)
            try:
                runner.run()
                ok = runner.results.is_all_pass and ok
            except signals.TestAbortAll:
                pass
            except:
                logging.exception('Exception when executing %s.',
                                  config.test_bed_name)
                ok = False
    if not ok:
        sys.exit(1)


def parse_mobly_cli_args(argv):
    """Parses cli args that are consumed by Mobly.

    This is the arg parsing logic for the default test_runner.main entry point.

    Multiple arg parsers can be applied to the same set of cli input. So you
    can use this logic in addition to any other args you want to parse. This
    function ignores the args that don't apply to default `test_runner.main`.

    Args:
        argv: A list that is then parsed as cli args. If None, defaults to cli
            input.

    Returns:
        Namespace containing the parsed args.
    """
    parser = argparse.ArgumentParser(description='Mobly Test Executable.')
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument('-c',
                       '--config',
                       nargs=1,
                       type=str,
                       metavar='<PATH>',
                       help='Path to the test configuration file.')
    group.add_argument(
        '-l',
        '--list_tests',
        action='store_true',
        help='Print the names of the tests defined in a script without '
        'executing them.')
    parser.add_argument('--tests',
                        '--test_case',
                        nargs='+',
                        type=str,
                        metavar='[test_a test_b...]',
                        help='A list of tests in the test class to execute.')
    parser.add_argument('-tb',
                        '--test_bed',
                        nargs='+',
                        type=str,
                        metavar='[<TEST BED NAME1> <TEST BED NAME2> ...]',
                        help='Specify which test beds to run tests on.')
    if not argv:
        argv = sys.argv[1:]
    return parser.parse_known_args(argv)[0]


def _find_test_class():
    """Finds the test class in a test script.

    Walk through module members and find the subclass of BaseTestClass. Only
    one subclass is allowed in a test script.

    Returns:
        The test class in the test module.
    """
    test_classes = []
    main_module_members = sys.modules['__main__']
    for _, module_member in main_module_members.__dict__.items():
        if inspect.isclass(module_member):
            if issubclass(module_member, base_test.BaseTestClass):
                test_classes.append(module_member)
    if len(test_classes) != 1:
        logging.error('Expected 1 test class per file, found %s.',
                      [t.__name__ for t in test_classes])
        sys.exit(1)
    return test_classes[0]


def _print_test_names(test_class):
    """Prints the names of all the tests in a test module.

    If the module has generated tests defined based on controller info, this
    may not be able to print the generated tests.

    Args:
        test_class: module, the test module to print names from.
    """
    cls = test_class(config_parser.TestRunConfig())
    try:
        cls.setup_generated_tests()
    except:
        logging.exception('Failed to retrieve generated tests.')
    print('==========> %s <==========' % cls.TAG)
    for name in cls.get_existing_test_names():
        print(name)


class TestRunner(object):
    """The class that instantiates test classes, executes tests, and
    report results.

    One TestRunner instance is associated with one specific output folder and
    testbed. TestRunner.run() will generate a single set of output files and
    results for all tests that have been added to this runner.

    Attributes:
        self.results: The test result object used to record the results of
            this test run.
    """
    class _TestRunInfo(object):
        """Identifies one test class to run, which tests to run, and config to
        run it with.
        """
        def __init__(self,
                     config,
                     test_class,
                     tests=None,
                     test_class_name_suffix=None):
            self.config = config
            self.test_class = test_class
            self.test_class_name_suffix = test_class_name_suffix
            self.tests = tests

    def __init__(self, log_dir, test_bed_name):
        """Constructor for TestRunner.

        Args:
            log_dir: string, root folder where to write logs
            test_bed_name: string, name of the testbed to run tests on
        """
        self._log_dir = log_dir
        self._test_bed_name = test_bed_name

        self.results = records.TestResult()
        self._test_run_infos = []

        # Set default logging values. Necessary if `run` is used outside of the
        # `mobly_logger` context.
        self._update_log_path()

    def _update_log_path(self):
        """Updates the logging values with the current timestamp."""
        self._start_time = logger.get_log_file_timestamp()
        self._log_path = os.path.join(self._log_dir, self._test_bed_name,
                                      self._start_time)

    @contextlib.contextmanager
    def mobly_logger(self, alias='latest'):
        """Starts and stops a logging context for a Mobly test run.

        Args:
          alias: optional string, the name of the latest log alias directory to
              create. If a falsy value is specified, then the directory will not
              be created.

        Yields:
            The host file path where the logs for the test run are stored.
        """
        self._update_log_path()
        logger.setup_test_logger(self._log_path,
                                 self._test_bed_name,
                                 alias=alias)
        try:
            yield self._log_path
        finally:
            logger.kill_test_logger(logging.getLogger())

    def add_test_class(self, config, test_class, tests=None, name_suffix=None):
        """Adds tests to the execution plan of this TestRunner.

        Args:
            config: config_parser.TestRunConfig, configuration to execute this
                test class with.
            test_class: class, test class to execute.
            tests: list of strings, optional list of test names within the
                class to execute.
            name_suffix: string, suffix to append to the class name for
                reporting. This is used for differentiating the same class
                executed with different parameters in a suite.

        Raises:
            Error: if the provided config has a log_path or test_bed_name which
                differs from the arguments provided to this TestRunner's
                constructor.
        """
        if self._log_dir != config.log_path:
            raise Error(
                'TestRunner\'s log folder is "%s", but a test config with a '
                'different log folder ("%s") was added.' %
                (self._log_dir, config.log_path))
        if self._test_bed_name != config.test_bed_name:
            raise Error(
                'TestRunner\'s test bed is "%s", but a test config with a '
                'different test bed ("%s") was added.' %
                (self._test_bed_name, config.test_bed_name))
        self._test_run_infos.append(
            TestRunner._TestRunInfo(config=config,
                                    test_class=test_class,
                                    tests=tests,
                                    test_class_name_suffix=name_suffix))

    def _run_test_class(self, config, test_class, tests=None):
        """Instantiates and executes a test class.

        If tests is None, the tests listed in self.tests will be executed
        instead. If self.tests is empty as well, every test in this test class
        will be executed.

        Args:
            config: A config_parser.TestRunConfig object.
            test_class: class, test class to execute.
            tests: Optional list of test names within the class to execute.
        """
        with test_class(config) as test_instance:
            logging.debug('Executing test class "%s" with config: %s',
                          test_class.__name__, config)
            try:
                cls_result = test_instance.run(tests)
                self.results += cls_result
            except signals.TestAbortAll as e:
                self.results += e.results
                raise e

    def run(self):
        """Executes tests.

        This will instantiate controller and test classes, execute tests, and
        print a summary.

        Raises:
            Error: if no tests have previously been added to this runner using
                add_test_class(...).
        """
        if not self._test_run_infos:
            raise Error('No tests to execute.')

        # Ensure the log path exists. Necessary if `run` is used outside of the
        # `mobly_logger` context.
        utils.create_dir(self._log_path)

        summary_writer = records.TestSummaryWriter(
            os.path.join(self._log_path, records.OUTPUT_FILE_SUMMARY))
        try:
            for test_run_info in self._test_run_infos:
                # Set up the test-specific config
                test_config = test_run_info.config.copy()
                test_config.log_path = self._log_path
                test_config.summary_writer = summary_writer
                test_config.test_class_name_suffix = test_run_info.test_class_name_suffix
                try:
                    self._run_test_class(config=test_config,
                                         test_class=test_run_info.test_class,
                                         tests=test_run_info.tests)
                except signals.TestAbortAll as e:
                    logging.warning(
                        'Abort all subsequent test classes. Reason: %s', e)
                    raise
        finally:
            summary_writer.dump(self.results.summary_dict(),
                                records.TestSummaryEntryType.SUMMARY)
            # Stop and show summary.
            msg = '\nSummary for test run %s@%s: %s\n' % (
                self._test_bed_name, self._start_time,
                self.results.summary_str())
            logging.info(msg.strip())
