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