# 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 builtins import str

import copy
import io
import pprint
import os
import yaml

from mobly import keys
from mobly import utils

# An environment variable defining the base location for Mobly logs.
ENV_MOBLY_LOGPATH = 'MOBLY_LOGPATH'
_DEFAULT_LOG_PATH = '/tmp/logs/mobly/'


class MoblyConfigError(Exception):
  """Raised when there is a problem in test configuration file."""


def _validate_test_config(test_config):
  """Validates the raw configuration loaded from the config file.

  Making sure the required key 'TestBeds' is present.
  """
  required_key = keys.Config.key_testbed.value
  if required_key not in test_config:
    raise MoblyConfigError('Required key %s missing in test config.' %
                           required_key)


def _validate_testbed_name(name):
  """Validates the name of a test bed.

  Since test bed names are used as part of the test run id, it needs to meet
  certain requirements.

  Args:
    name: The test bed's name specified in config file.

  Raises:
    MoblyConfigError: The name does not meet any criteria.
  """
  if not name:
    raise MoblyConfigError("Test bed names can't be empty.")
  name = str(name)
  for char in name:
    if char not in utils.valid_filename_chars:
      raise MoblyConfigError('Char "%s" is not allowed in test bed names.' %
                             char)


def _validate_testbed_configs(testbed_configs):
  """Validates the testbed configurations.

  Args:
    testbed_configs: A list of testbed configuration dicts.

  Raises:
    MoblyConfigError: Some parts of the configuration is invalid.
  """
  seen_names = set()
  # Cross checks testbed configs for resource conflicts.
  for config in testbed_configs:
    # Check for conflicts between multiple concurrent testbed configs.
    # No need to call it if there's only one testbed config.
    name = config[keys.Config.key_testbed_name.value]
    _validate_testbed_name(name)
    # Test bed names should be unique.
    if name in seen_names:
      raise MoblyConfigError('Duplicate testbed name %s found.' % name)
    seen_names.add(name)


def load_test_config_file(test_config_path, tb_filters=None):
  """Processes the test configuration file provied by user.

  Loads the configuration file into a dict, unpacks each testbed
  config into its own dict, and validate the configuration in the
  process.

  Args:
    test_config_path: Path to the test configuration file.
    tb_filters: A subset of test bed names to be pulled from the config
      file. If None, then all test beds will be selected.

  Returns:
    A list of test configuration dicts to be passed to
    test_runner.TestRunner.
  """
  configs = _load_config_file(test_config_path)
  if tb_filters:
    tbs = []
    for tb in configs[keys.Config.key_testbed.value]:
      if tb[keys.Config.key_testbed_name.value] in tb_filters:
        tbs.append(tb)
    if len(tbs) != len(tb_filters):
      raise MoblyConfigError(
          'Expect to find %d test bed configs, found %d. Check if'
          ' you have the correct test bed names.' % (len(tb_filters), len(tbs)))
    configs[keys.Config.key_testbed.value] = tbs
  mobly_params = configs.get(keys.Config.key_mobly_params.value, {})
  # Decide log path.
  log_path = mobly_params.get(keys.Config.key_log_path.value, _DEFAULT_LOG_PATH)
  if ENV_MOBLY_LOGPATH in os.environ:
    log_path = os.environ[ENV_MOBLY_LOGPATH]
  log_path = utils.abs_path(log_path)
  # Validate configs
  _validate_test_config(configs)
  _validate_testbed_configs(configs[keys.Config.key_testbed.value])
  # Transform config dict from user-facing key mapping to internal config object.
  test_configs = []
  for original_bed_config in configs[keys.Config.key_testbed.value]:
    test_run_config = TestRunConfig()
    test_run_config.testbed_name = original_bed_config[
        keys.Config.key_testbed_name.value]
    # Deprecated, use testbed_name
    test_run_config.test_bed_name = test_run_config.testbed_name
    test_run_config.log_path = log_path
    test_run_config.controller_configs = original_bed_config.get(
        keys.Config.key_testbed_controllers.value, {})
    test_run_config.user_params = original_bed_config.get(
        keys.Config.key_testbed_test_params.value, {})
    test_configs.append(test_run_config)
  return test_configs


def _load_config_file(path):
  """Loads a test config file.

  The test config file has to be in YAML format.

  Args:
    path: A string that is the full path to the config file, including the
      file name.

  Returns:
    A dict that represents info in the config file.
  """
  with io.open(utils.abs_path(path), 'r', encoding='utf-8') as f:
    conf = yaml.safe_load(f)
    return conf


class TestRunConfig(object):
  """The data class that holds all the information needed for a test run.

  Attributes:
    log_path: string, specifies the root directory for all logs written by
      a test run.
    test_bed_name: [Deprecated, use 'testbed_name' instead]
      string, the name of the test bed used by a test run.
    testbed_name: string, the name of the test bed used by a test run.
    controller_configs: dict, configs used for instantiating controller
      objects.
    user_params: dict, all the parameters to be consumed by the test logic.
    summary_writer: records.TestSummaryWriter, used to write elements to
      the test result summary file.
    test_class_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.
  """

  def __init__(self):
    # Init value is an empty string to avoid string joining errors.
    self.log_path = ''
    # Deprecated, use 'testbed_name'
    self.test_bed_name = None
    self.testbed_name = None
    self.controller_configs = {}
    self.user_params = {}
    self.summary_writer = None
    self.test_class_name_suffix = None

  def copy(self):
    """Returns a deep copy of the current config.
    """
    return copy.deepcopy(self)

  def __str__(self):
    content = dict(self.__dict__)
    content.pop('summary_writer')
    return pprint.pformat(content)
