# Copyright 2016 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 json
import logging
import os

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 adb_utils
from autotest_lib.server import constants
from autotest_lib.server.cros import dnsname_mangler
from autotest_lib.server.hosts import adb_host
from autotest_lib.site_utils import sponge_utils

DEFAULT_ACTS_INTERNAL_DIRECTORY = 'tools/test/connectivity/acts'

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

TEST_DIR_NAME = 'tests'
FRAMEWORK_DIR_NAME = 'framework'
SETUP_FILE_NAME = 'setup.py'
CONFIG_DIR_NAME = 'autotest_config'
CAMPAIGN_DIR_NAME = 'autotest_campaign'
LOG_DIR_NAME = 'logs'
ACTS_EXECUTABLE_IN_FRAMEWORK = 'acts/bin/act.py'

ACTS_TESTPATHS_ENV_KEY = 'ACTS_TESTPATHS'
ACTS_LOGPATH_ENV_KEY = 'ACTS_LOGPATH'
ACTS_PYTHONPATH_ENV_KEY = 'PYTHONPATH'


def create_acts_package_from_current_artifact(test_station, job_repo_url,
                                              target_zip_file):
    """Creates an acts package from the build branch being used.

    Creates an acts artifact from the build branch being used. This is
    determined by the job_repo_url passed in.

    @param test_station: The teststation that should be creating the package.
    @param job_repo_url: The job_repo_url to get the build info from.
    @param target_zip_file: The zip file to create form the artifact on the
                            test_station.

    @returns An ActsPackage containing all the information about the zipped
             artifact.
    """
    build_info = adb_host.ADBHost.get_build_info_from_build_url(job_repo_url)

    return create_acts_package_from_artifact(
            test_station, build_info['branch'], build_info['target'],
            build_info['build_id'], job_repo_url, target_zip_file)


def create_acts_package_from_artifact(test_station, branch, target, build_id,
                                      job_repo_url, target_zip_file):
    """Creates an acts package from a specified branch.

    Grabs the packaged acts artifact from the branch and places it on the
    test_station.

    @param test_station: The teststation that should be creating the package.
    @param branch: The name of the branch where the artifact is to be pulled.
    @param target: The name of the target where the artifact is to be pulled.
    @param build_id: The build id to pull the artifact from.
    @param job_repo_url: The job repo url for where to pull build from.
    @param target_zip_file: The zip file to create on the teststation.

    @returns An ActsPackage containing all the information about the zipped
             artifact.
    """
    devserver_url = dev_server.AndroidBuildServer.get_server_url(job_repo_url)
    devserver = dev_server.AndroidBuildServer(devserver_url)
    devserver.trigger_download(target,
                               build_id,
                               branch,
                               files='acts.zip',
                               synchronous=True)

    download_ulr = os.path.join(job_repo_url, 'acts.zip')

    test_station.download_file(download_ulr, target_zip_file)

    return ActsPackage(test_station, target_zip_file)


def create_acts_package_from_zip(test_station, zip_location, target_zip_file):
    """Creates an acts package from an existing zip.

    Creates an acts package from a zip file that already sits on the drone.

    @param test_station: The teststation to create the package on.
    @param zip_location: The location of the zip on the drone.
    @param target_zip_file: The zip file to create on the teststaiton.

    @returns An ActsPackage containing all the information about the zipped
             artifact.
    """
    if not os.path.isabs(zip_location):
        zip_location = os.path.join(CONFIG_FOLDER_LOCATION, 'acts_artifacts',
                                    zip_location)

    remote_zip = test_station.send_file(zip_location, target_zip_file)

    return ActsPackage(test_station, remote_zip)


class ActsPackage(object):
    """A packaged version of acts on a teststation."""
    def __init__(self, test_station, zip_file_path):
        """
        @param test_station: The teststation this package is on.
        @param zip_file_path: The path to the zip file on the test station that
                              holds the package on the teststation.
        """
        self.test_station = test_station
        self.zip_file = zip_file_path

    def create_container(self,
                         container_directory,
                         internal_acts_directory=None):
        """Unpacks this package into a container.

        Unpacks this acts package into a container to interact with acts.

        @param container_directory: The directory on the teststation to hold
                                    the container.
        @param internal_acts_directory: The directory inside of the package
                                        that holds acts.

        @returns: An ActsContainer with info on the unpacked acts container.
        """
        self.test_station.run('unzip "%s" -x -d "%s"' %
                              (self.zip_file, container_directory))

        return ActsContainer(self.test_station,
                             container_directory,
                             acts_directory=internal_acts_directory)

    def create_enviroment(self,
                          container_directory,
                          testbed,
                          testbed_name=None,
                          internal_acts_directory=None):
        """Unpacks this package into an acts testing enviroment.

        Unpacks this acts package into a test enviroment to test with acts.

        @param container_directory: The directory on the teststation to hold
                                    the test enviroment.
        @param testbed: The testbed that the test enviroment
                        will be testing on.
        @param testbed_name: An overriding name for the testbed.
        @param internal_acts_directory: The directory inside of the package
                                        that holds acts.

        @returns: An ActsTestingEnviroment with info on the unpacked
                  acts testing enviroment.
        """
        if testbed.teststation != self.test_station:
            raise error.TestError('Creating a contianer for a testbed on a '
                                   'different teststation is not allowed.')

        self.test_station.run('unzip "%s" -x -d "%s"' %
                              (self.zip_file, container_directory))

        return ActsTestingEnviroment(testbed=testbed,
                container_directory=container_directory,
                testbed_name=testbed_name,
                acts_directory=internal_acts_directory)


class AndroidTestingEnviroment(object):
    """A container for testing android devices on a test station."""
    def __init__(self, testbed, testbed_name=None):
        """Creates a new android testing enviroment.

        @param testbed: The testbed to test on.
        @param testbed_name: An overriding name for the testbed.
        """
        self.testbed = testbed

        if not testbed_name:
            # If no override is given get the name from the hostname.
            hostname = testbed.hostname
            if dnsname_mangler.is_ip_address(hostname):
                testbed_name = hostname
            else:
                testbed_name = hostname.split('.')[0]

        self.testbed_name = testbed_name

    def install_sl4a_apk(self):
        """Install sl4a to a test bed."""
        for serial, adb_host in self.testbed.get_adb_devices().iteritems():
            adb_utils.install_apk_from_build(
                    adb_host,
                    constants.SL4A_APK,
                    constants.SL4A_ARTIFACT,
                    package_name=constants.SL4A_PACKAGE)

    def install_apk(self, apk_info):
        """Installs an additional apk on all adb devices.

        @param apk_info: A dictionary contianing the apk info. This dictionary
                         should contain the keys:
                            apk="Name of the apk",
                            package="Name of the package".
                            artifact="Name of the artifact", if missing
                                      the package name is used."
        """
        for serial, adb_host in self.testbed.get_adb_devices().iteritems():
            adb_utils.install_apk_from_build(
                    adb_host,
                    apk_info['apk'],
                    apk_info.get('artifact') or constants.SL4A_ARTIFACT,
                    package_name=apk_info['package'])


class ActsContainer(object):
    """A container for working with acts."""
    def __init__(self,
                 test_station,
                 container_directory,
                 acts_directory=None):
        """
        @param test_station: The test station that the container is on.
        @param container_directory: The directory on the teststation this
                                    container operates out of.
        @param acts_directory: The directory within the container that holds
                               acts. If none then it defaults to
                               DEFAULT_ACTS_INTERNAL_DIRECTORY.
        """
        self.test_station = test_station
        self.container_directory = container_directory

        if not acts_directory:
            acts_directory = DEFAULT_ACTS_INTERNAL_DIRECTORY

        if not os.path.isabs(acts_directory):
            self.acts_directory = os.path.join(container_directory,
                                               acts_directory)
        else:
            self.acts_directory = acts_directory

        self.tests_directory = os.path.join(self.acts_directory, TEST_DIR_NAME)
        self.framework_directory = os.path.join(self.acts_directory,
                                                FRAMEWORK_DIR_NAME)

        self.acts_file = os.path.join(self.framework_directory,
                                      ACTS_EXECUTABLE_IN_FRAMEWORK)

        self.setup_file = os.path.join(self.framework_directory,
                                       SETUP_FILE_NAME)

    def get_test_paths(self):
        """Get all test paths within this container.

        Gets all paths that hold tests within the container.

        @returns: A list of paths on the teststation that hold tests.
        """
        get_test_paths_result = self.test_station.run('find %s -type d' %
                                                      self.tests_directory)
        test_search_dirs = get_test_paths_result.stdout.splitlines()
        return test_search_dirs

    def get_python_path(self):
        """Get the python path being used.

        Gets the python path that will be set in the enviroment for this
        container.

        @returns: A string of the PYTHONPATH enviroment variable to be used.
        """
        return '%s:$PYTHONPATH' % self.framework_directory

    def get_enviroment(self):
        """Gets the enviroment variables to be used for this container.

        @returns: A dictionary of enviroment variables to be used by this
                  container.
        """
        env = {ACTS_TESTPATHS_ENV_KEY: ':'.join(self.get_test_paths()),
               ACTS_LOGPATH_ENV_KEY: self.log_directory,
               ACTS_PYTHONPATH_ENV_KEY: self.get_python_path()}

        return env

    def upload_file(self, src, dst):
        """Uploads a file to be used by the container.

        Uploads a file from the drone to the test staiton to be used by the
        test container.

        @param src: The source file on the drone. If a relative path is given
                    it is assumed to exist in CONFIG_FOLDER_LOCATION.
        @param dst: The destination on the teststation. If a relative path is
                    given it is assumed that it is within the container.

        @returns: The full path on the teststation.
        """
        if not os.path.isabs(src):
            src = os.path.join(CONFIG_FOLDER_LOCATION, src)

        if not os.path.isabs(dst):
            dst = os.path.join(self.container_directory, dst)

        path = os.path.dirname(dst)
        result = self.test_station.run('mkdir "%s"' % path,
                                       ignore_status=True)

        original_dst = dst
        if os.path.basename(src) == os.path.basename(dst):
            dst = os.path.dirname(dst)

        self.test_station.send_file(src, dst)

        return original_dst

    def setup_enviroment(self, python_bin='python'):
        """Sets up the teststation system enviroment so the container can run.

        Prepares the remote system so that the container can run. This involves
        uninstalling all versions of acts for the version of python being
        used and installing all needed dependencies.

        @param python_bin: The python binary to use.
        """
        uninstall_command = '%s %s uninstall' % (python_bin, self.setup_file)
        install_deps_command = '%s %s install_deps' % (python_bin,
                                                       self.setup_file)

        self.test_station.run(uninstall_command)
        self.test_station.run(install_deps_command)


class ActsTestingEnviroment(ActsContainer, AndroidTestingEnviroment):
    """A container for running acts tests with a contained version of acts."""
    def __init__(self,
                 container_directory,
                 testbed,
                 testbed_name=None,
                 acts_directory=None):
        """
        @param testbed: The testbed to test on.
        @param container_directory: The directory on the teststation this
                                    container operates out of.
        @param testbed_name: An overriding name for the testbed.
        @param acts_directory: The directory within the container that holds
                               acts. If none then it defaults to
                               DEFAULT_ACTS_INTERNAL_DIRECTORY.
        """
        AndroidTestingEnviroment.__init__(self, testbed,
                                          testbed_name=testbed_name)

        ActsContainer.__init__(self, testbed.teststation,
                               container_directory=container_directory,
                               acts_directory=acts_directory)

        self.config_location = os.path.join(self.container_directory,
                                            CONFIG_DIR_NAME)

        self.log_directory = os.path.join(self.container_directory,
                                          LOG_DIR_NAME)

        self.acts_file = os.path.join(self.framework_directory,
                                      ACTS_EXECUTABLE_IN_FRAMEWORK)

        self.working_directory = os.path.join(container_directory,
                                              CONFIG_DIR_NAME)
        self.test_station.run('mkdir %s' % self.working_directory,
                ignore_status=True)

        self.configs = {}
        self.campaigns = {}

    def upload_config(self, config_file):
        """Uploads a config file to the container.

        Uploads a config file to the config folder in the container.

        @param config_file: The config file to upload. This must be a file
                            within the autotest_config directory under the
                            CONFIG_FOLDER_LOCATION.

        @returns: The full path of the config on the test staiton.
        """
        full_name = os.path.join(CONFIG_DIR_NAME, config_file)

        full_path = self.upload_file(full_name, full_name)
        self.configs[config_file] = full_path

        return full_path

    def upload_campaign(self, campaign_file):
        """Uploads a campaign file to the container.

        Uploads a campaign file to the campaign folder in the container.

        @param campaign_file: The campaign file to upload. This must be a file
                              within the autotest_campaign directory under the
                              CONFIG_FOLDER_LOCATION.

        @returns: The full path of the campaign on the test staiton.
        """
        full_name = os.path.join(CAMPAIGN_DIR_NAME, campaign_file)

        full_path = self.upload_file(full_name, full_name)
        self.campaigns[campaign_file] = full_path

        return full_path

    def run_test(self,
                 config,
                 campaign=None,
                 test_case=None,
                 extra_env={},
                 python_bin='python',
                 timeout=7200):
        """Runs a test within the container.

        Runs a test within a container using the given settings.

        @param config: The name of the config file to use as the main config.
                       This should have already been uploaded with
                       upload_config. The string passed into upload_config
                       should be used here.
        @param campaign: The campaign file to use for this test. If none then
                         test_case is assumed. This file should have already
                         been uploaded with upload_campaign. The string passed
                         into upload_campaign should be used here.
        @param test_case: The test case to run the test with. If none then the
                          campaign will be used.
        @param extra_env: Extra enviroment variables to run the test with.
        @param python_bin: The python binary to execute the test with.
        @param timeout: How many seconds to wait before timing out.

        @returns: The results of the test run.
        """
        if not config in self.configs:
            # Check if the config has been uploaded and upload if it hasn't
            self.upload_config(config)

        full_config = self.configs[config]

        if campaign:
            # When given a campaign check if it's upload.
            if not campaign in self.campaigns:
                self.upload_campaign(campaign)

            full_campaign = self.campaigns[campaign]
        else:
            full_campaign = None

        full_env = self.get_enviroment()

        # Setup enviroment variables.
        if extra_env:
            for k, v in extra_env.items():
                full_env[k] = extra_env

        logging.info('Using env: %s', full_env)
        exports = ('export %s=%s' % (k, v) for k, v in full_env.items())
        env_command = ';'.join(exports)

        # Make sure to execute in the working directory.
        command_setup = 'cd %s' % self.working_directory

        act_base_cmd = '%s %s -c %s -tb %s ' % (python_bin, self.acts_file,
                                                full_config, self.testbed_name)

        # Format the acts command based on what type of test is being run.
        if test_case and campaign:
            raise error.TestError(
                    'campaign and test_file cannot both have a value.')
        elif test_case:
            act_cmd = '%s -tc %s' % (act_base_cmd, test_case)
        elif campaign:
            act_cmd = '%s -tf %s' % (act_base_cmd, full_campaign)
        else:
            raise error.TestFail('No tests was specified!')

        # Format all commands into a single command.
        command_list = [command_setup, env_command, act_cmd]
        full_command = '; '.join(command_list)

        try:
            # Run acts on the remote machine.
            act_result = self.test_station.run(full_command, timeout=timeout)
            excep = None
        except Exception as e:
            # Catch any error to store in the results.
            act_result = None
            excep = e

        return ActsTestResults(test_case or campaign,
                               self.testbed,
                               testbed_name=self.testbed_name,
                               run_result=act_result,
                               log_directory=self.log_directory,
                               exception=excep)


class ActsTestResults(object):
    """The packaged results of a test run."""
    acts_result_to_autotest = {
        'PASS': 'GOOD',
        'FAIL': 'FAIL',
        'UNKNOWN': 'WARN',
        'SKIP': 'ABORT'
    }

    def __init__(self,
                 name,
                 testbed,
                 testbed_name=None,
                 run_result=None,
                 log_directory=None,
                 exception=None):
        """
        @param name: A name to identify the test run.
        @param testbed: The testbed that ran the test.
        @param testbed_name: The name the testbed was run with, if none the
                             default name of the testbed is used.
        @param run_result: The raw i/o result of the test run.
        @param log_directory: The directory that acts logged to.
        @param exception: An exception that was thrown while running the test.
        """
        self.name = name
        self.run_result = run_result
        self.exception = exception
        self.log_directory = log_directory
        self.test_station = testbed.teststation

        self.testbed = testbed
        if not testbed_name:
            # If no override is given get the name from the hostname.
            hostname = testbed.hostname
            if dnsname_mangler.is_ip_address(hostname):
                self.testbed_name = hostname
            else:
                self.testbed_name = hostname.split('.')[0]
        else:
            self.testbed_name = testbed_name

        self.reported_to = set()

        self.json_results = {}
        self.results_dir = None
        if self.log_directory:
            self.results_dir = os.path.join(self.log_directory,
                                            self.testbed_name, 'latest')
            results_file = os.path.join(self.results_dir,
                                        'test_run_summary.json')
            cat_log_result = self.test_station.run('cat %s' % results_file,
                                                   ignore_status=True)
            if not cat_log_result.exit_status:
                self.json_results = json.loads(cat_log_result.stdout)

    def log_output(self):
        """Logs the output of the test."""
        if self.run_result:
            logging.debug('ACTS Output:\n%s', self.run_result.stdout)

    def rethrow_exception(self):
        """Re-throws the exception thrown during the test."""
        if self.exception:
            raise self.exception

    def upload_to_local(self, local_dir):
        """Saves all acts results to a local directory.

        @param local_dir: The directory on the local machine to save all results
                          to.
        """
        if self.results_dir:
            self.test_station.get_file(self.results_dir, local_dir)

    def upload_to_sponge(self, test):
        """Uploads the results to sponge.

        @param test: The autotest test object to upload.
        """
        if self.results_dir:
            self.report_to_autotest(test)
            summary_file = os.path.join(test.resultsdir,
                                        'test_run_summary.json')
            sponge_utils.upload_results_in_test(test, acts_summary=summary_file)

    def report_to_autotest(self, test):
        """Reports the results to an autotest test object.

        Reports the results to the test and saves all acts results under the
        tests results directory.

        @param test: The autotest test object to report to. If this test object
                     has already recived our report then this call will be
                     ignored.
        """
        if test in self.reported_to:
            return

        if self.results_dir:
            self.upload_to_local(test.resultsdir)

        if not 'Results' in self.json_results:
            return

        results = self.json_results['Results']
        for result in results:
            verdict = self.acts_result_to_autotest[result['Result']]
            details = result['Details']
            test.job.record(verdict, None, self.name, status=(details or ''))

        self.reported_to.add(test)
