# 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.

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, 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,
                        testbed_name=config.testbed_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.testbed_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',
                     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.

  Raises:
    SystemExit: Raised if the number of test classes is not exactly one.
  """
  try:
    return utils.find_subclass_in_module(base_test.BaseTestClass,
                                         sys.modules['__main__'])
  except ValueError:
    logging.exception('Exactly one subclass of `base_test.BaseTestClass`'
                      ' should be in the main file.')
    sys.exit(1)


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())
  test_names = []
  try:
    cls.setup_generated_tests()
    test_names = cls.get_existing_test_names()
  except:
    logging.exception('Failed to retrieve generated tests.')
  finally:
    cls._controller_manager.unregister_controllers()
  print('==========> %s <==========' % cls.TAG)
  for name in test_names:
    print(name)


class TestRunner:
  """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:
    """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, testbed_name):
    """Constructor for TestRunner.

    Args:
      log_dir: string, root folder where to write logs
      testbed_name: string, name of the testbed to run tests on
    """
    self._log_dir = log_dir
    self._testbed_name = testbed_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._root_output_path = os.path.join(self._log_dir, self._testbed_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._root_output_path,
                             self._testbed_name,
                             alias=alias)
    try:
      yield self._root_output_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 testbed_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._testbed_name != config.testbed_name:
      raise Error('TestRunner\'s test bed is "%s", but a test config with a '
                  'different test bed ("%s") was added.' %
                  (self._testbed_name, config.testbed_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.
    """
    test_instance = test_class(config)
    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._root_output_path)

    summary_writer = records.TestSummaryWriter(
        os.path.join(self._root_output_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._root_output_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._testbed_name, self._start_time, self.results.summary_str())
      logging.info(msg.strip())
