# Copyright 2015 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import os
import logging
import re

import common
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import global_config
from autotest_lib.client.common_lib.cros import dev_server
from autotest_lib.server import test
from autotest_lib.server.hosts import adb_host
from autotest_lib.server.hosts import host_info
from autotest_lib.site_utils import acts_lib
from server.cros import dnsname_mangler

CONFIG = global_config.global_config

CONFIG_FOLDER_LOCATION = global_config.global_config.get_config_value(
    'ACTS', 'acts_config_folder', default='')

TEST_CONFIG_FILE_FOLDER = os.path.join(CONFIG_FOLDER_LOCATION,
                                       'autotest_config')

TEST_CAMPAIGN_FILE_FOLDER = os.path.join(CONFIG_FOLDER_LOCATION,
                                         'autotest_campaign')
DEFAULT_TEST_RELATIVE_LOG_PATH = 'results/logs'


def get_global_config_value_regex(section, regex):
    """Get config values from global config based on regex of the key.

    @param section: Section of the config, e.g., CLIENT.
    @param regex: Regular expression of the key pattern.

    @return: A dictionary of all config values matching the regex. Value is
             assumed to be comma separated, and is converted to a list.
    """
    configs = CONFIG.get_config_value_regex(section, regex)
    result = {}
    for key, value in configs.items():
        match = re.match(regex, key)
        result[match.group(1)] = [v.strip() for v in value.split(',')
                                  if v.strip()]
    return result


class android_ACTS(test.test):
    """Run an Android CTS test case.

    Component relationship:
    Workstation ----(ssh)---> TestStation -----(adb)-----> Android DUT
    This code runs on Workstation.
    """
    version = 1

    BRANCH_ALIAS_PATTERN = 'acts_branch_alias_(.*)'
    aliases_map = get_global_config_value_regex('ACTS', BRANCH_ALIAS_PATTERN)

    def run_once(self,
                 testbed=None,
                 config_file=None,
                 testbed_name=None,
                 test_case=None,
                 test_file=None,
                 additional_configs=[],
                 additional_apks=[],
                 override_build_url=None,
                 override_build=None,
                 override_acts_zip=None,
                 override_internal_acts_dir=None,
                 override_python_bin='python',
                 acts_timeout=7200,
                 perma_path=None,
                 additional_cmd_line_params=None,
                 branch_mappings={},
                 valid_job_urls_only=False,
                 testtracker_project_id=None,
                 testtracker_extra_env=None,
                 testtracker_owner=None):
        """Runs an acts test case.

        @param testbed: The testbed to test on.
        @config_file: The main config file to use for running the test. This
                      should be relative to the autotest_config folder.
        @param test_case: The test case to run. Should be None when test_file
                          is given.
        @param test_file: The campaign file to run. Should be None when
                          test_case is given. This should be relative to the
                          autotest_campaign folder. If multiple are given,
                          multiple test cases will be run.
        @param additional_configs: Any additional config files to use.
                                   These should be relative to the
                                   autotest_config folder.
        @param additional_apks: An array of apk info dictionaries.
                                apk = Name of the apk (eg. sl4a.apk)
                                package = Name of the package (eg. test.tools)
                                artifact = Name of the artifact, if not given
                                           package is used.
        @param override_build_url: Deprecated, use override_build instead.
        @param override_build: The android build to fetch test artifacts from.
                               If not provided a default is selected from one
                               of the devices.
        @param override_acts_zip: If given a zip file on the drone is used
                                  rather than pulling a build.
        @param override_internal_acts_dir: The directory within the artifact
                                           where the acts framework folder
                                           lives.
        @param override_python_bin: Overrides the default python binary that
                                    is used.
        @param acts_timeout: How long to wait for acts to finish.
        @param valid_job_urls_only: Apps and resources will be downloaded and
                                    installed only on devices that have valid
                                    job urls.
        @param perma_path: If given a permantent path will be used rather than
                           a temp path.
        @para branch_mappings: A dictionary of branch names to branch names.
                               When pulling test resources, if the current
                               branch is found in the mapping it will use
                               the mapped branch instead.
        @param testtracker_project_id: ID to use for test tracker project.
        @param testtracker_extra_env: Extra environment info to publish
                                      with the results.
        """
        hostname = testbed.hostname
        if not testbed_name:
            if dnsname_mangler.is_ip_address(hostname):
                testbed_name = hostname
            else:
                testbed_name = hostname.split('.')[0]

        logging.info('Using testbed name %s', testbed_name)

        if not override_build:
            override_build = override_build_url

        valid_hosts = []
        if valid_job_urls_only:
            for v in testbed.get_adb_devices().values():
                try:
                    info = v.host_info_store.get()
                except host_info.StoreError:
                    pass
                else:
                    if v.job_repo_url_attribute in info.attributes:
                        valid_hosts.append(v)
        else:
            valid_hosts = list(testbed.get_adb_devices().values())

        if not valid_hosts:
            raise error.TestError('No valid hosts defined for this test, cannot'
                                  ' determine build to grab artifact from.')

        primary_host = valid_hosts[0]

        info = primary_host.host_info_store.get()
        job_repo_url = info.attributes.get(primary_host.job_repo_url_attribute,
                                           '')
        test_station = testbed.teststation
        if not perma_path:
            ts_tempfolder = test_station.get_tmp_dir()
        else:
            test_station.run('rm -fr "%s"' % perma_path)
            test_station.run('mkdir "%s"' % perma_path)
            ts_tempfolder = perma_path
        target_zip = os.path.join(ts_tempfolder, 'acts.zip')

        if override_build:
            build_pieces = override_build.split('/')
            job_build_branch = build_pieces[0]
            job_build_target = build_pieces[1]
            job_build_id = build_pieces[2]
        else:
            job_build_info = adb_host.ADBHost.get_build_info_from_build_url(
                    job_repo_url)
            job_build_branch = job_build_info['branch']
            job_build_target = job_build_info['target']
            job_build_id = job_build_info['build_id']

        if not override_build_url:
            branch_mapping_pieces = None
            if job_build_branch in branch_mappings:
                logging.info('Replacing branch %s -> %s',
                             job_build_branch,
                             branch_mappings[job_build_branch].strip())
                branch_mapping_pieces = branch_mappings[
                    job_build_branch].strip().split('/')
            elif job_build_branch in self.aliases_map:
                logging.info('Replacing branch %s -> %s',
                             job_build_branch,
                             self.aliases_map[job_build_branch][0].strip())
                branch_mapping_pieces = self.aliases_map[job_build_branch][
                    0].strip().split('/')

            if branch_mapping_pieces:
                job_build_branch = branch_mapping_pieces[0]

                if len(branch_mapping_pieces) > 1:
                    job_build_target = branch_mapping_pieces[1]

                if len(branch_mapping_pieces) > 2:
                    job_build_id = branch_mapping_pieces[2]
                else:
                    job_build_id = "LATEST"

        build_name = '%s/%s/%s' % (job_build_branch,
                                   job_build_target,
                                   job_build_id)
        devserver = dev_server.AndroidBuildServer.resolve(build_name,
                                                          primary_host.hostname)
        build_name = devserver.translate(build_name)
        build_branch, build_target, build_id = build_name.split('/')

        logging.info('Using build info BRANCH:%s, TARGET:%s, BUILD_ID:%s',
                     build_branch, build_target, build_id)

        if override_acts_zip:
            package = acts_lib.create_acts_package_from_zip(test_station,
                                                            override_acts_zip,
                                                            target_zip)
        else:
            package = acts_lib.create_acts_package_from_artifact(test_station,
                                                                 build_branch,
                                                                 build_target,
                                                                 build_id,
                                                                 devserver,
                                                                 target_zip)

        test_env = package.create_environment(
            container_directory=ts_tempfolder,
            testbed_name=testbed_name,
            devices=valid_hosts,
            internal_acts_directory=override_internal_acts_dir)

        test_env.install_sl4a_apk()

        for apk in additional_apks:
            test_env.install_apk(apk)

        test_env.setup_enviroment(python_bin=override_python_bin)

        test_env.upload_config(config_file)

        if additional_configs:
            for additional_config in additional_configs:
                test_env.upload_config(additional_config)

        if test_file:
            test_env.upload_campaign(test_file)

        results = test_env.run_test(
            config_file,
            campaign=test_file,
            test_case=test_case,
            python_bin=override_python_bin,
            timeout=acts_timeout,
            additional_cmd_line_params=additional_cmd_line_params)

        results.log_output()
        results.report_to_autotest(self)
        results.save_test_info(self)
        results.rethrow_exception()
