# Copyright (c) 2014 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 collections
import logging

from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import global_config
from autotest_lib.client.common_lib import utils
from autotest_lib.client.common_lib.cros import dev_server
from autotest_lib.client.common_lib.cros.network import ping_runner
from autotest_lib.server import hosts
from autotest_lib.server import site_linux_router
from autotest_lib.server import test
from autotest_lib.server.cros import dnsname_mangler
from autotest_lib.server.cros import provisioner
from autotest_lib.server.cros.network import wifi_test_context_manager


# Stable versions come from the builders.
# The builder version is used to build the URL of the corresponding image
# in Google Storage.
# The image version is a line from /etc/lsb-release in the corresponding image.
StableVersion = collections.namedtuple('StableVersion',
                                       ['builder_version', 'release_version'])

class network_WiFi_UpdateRouter(test.test):
    """Updates a router to the most recent stable version.

    This is not a test per se, since it does not test client behavior.  However
    it is advantageous to write this as a test so that we can schedule it to
    run periodically via the same infrastructure we use to run tests.

    Note that this test is very much patterned on provision_QuickProvision.

    """
    version = 1

    STABLE_VERSIONS = {
        ## crbug.com/1098024: these are left here as documentation of what the
        # last stable version is, but the current updater code does not support
        # them.
        'whirlwind': StableVersion('whirlwind-test-ap-tryjob/R85-13310.60.0-b4641849',
                                   '13310.60.2020_08_25_0212'),
        'gale': StableVersion('gale-test-ap-tryjob/R88-13597.100.0-b4802789',
                              '13597.100.2021_02_22_0025'),
    }

    # List of files to remove.
    FILES_TO_REMOVE = ['/var/spool/crash/*', '/tmp/*',
                       '/var/lib/metrics/uma-events']


    def get_release_version(self, host):
        result = host.run('cat /etc/lsb-release')
        for line in result.stdout.splitlines():
            if line.startswith('CHROMEOS_RELEASE_VERSION='):
                return line.split('=', 1)[1]


    def get_update_url(self, ds_url, image):
        CONFIG = global_config.global_config
        IMAGE_URL_PATTERN = CONFIG.get_config_value(
                'CROS', 'image_url_pattern', type=str)
        return IMAGE_URL_PATTERN % (ds_url, image)


    def warmup(self, raw_cmdline_args):
        """Possibly parse the router hostname from the commandline.

        @param raw_cmdline_args raw input from autotest.

        """
        cmdline_args = utils.args_to_dict(raw_cmdline_args)
        logging.info('Running wifi test with commandline arguments: %r',
                     cmdline_args)
        self._router_hostname_from_cmdline = cmdline_args.get(
                wifi_test_context_manager.WiFiTestContextManager. \
                        CMDLINE_ROUTER_ADDR)


    def freeup_disk_space(self, device_host):
        """Remove files to free up disk space.

        @param device_host: router / pcap host object

        """
        for path in self.FILES_TO_REMOVE:
            device_host.run('rm -rf %s' % path, ignore_status=True)

    def stop_recover_duts(self, device_host):
        """Stop running recover_duts on the host.

        b/177380545: recover_duts is currently providing negative value on
        routers. TBD: decided whether we should re-enable this when router
        images are updated to fix hang issues?

        @param device_host: router / pcap host object
        """
        device_host.run('rm -f %s' % provisioner.LAB_MACHINE_FILE,
                        ignore_status=True)
        device_host.run('stop recover_duts', ignore_status=True)

    def run_once(self, host, is_pcap=False):
        """Update router / packet capture associated with host.

        @param host DUT connected to AP/Pcap that needs update

        """
        if is_pcap:
            device_hostname = dnsname_mangler.get_pcap_addr(
                    client_hostname=host.hostname)
        else:
            device_hostname = site_linux_router.build_router_hostname(
                client_hostname=host.hostname,
                router_hostname=self._router_hostname_from_cmdline)

        ping_helper = ping_runner.PingRunner()
        if not ping_helper.simple_ping(device_hostname):
            # Pcap devices aren't always present. Just claim Not Applicable if
            # we couldn't find it.
            e = error.TestNAError if is_pcap else error.TestError
            raise e('%s not found / is down.' % device_hostname)

        # Use CrosHost for all router/pcap hosts and avoid host detection.
        # Host detection would use JetstreamHost for Whirlwind routers.
        # JetstreamHost assumes ap-daemons are running.
        # Testbed routers run the testbed-ap profile with no ap-daemons.
        # TODO(ecgh): crbug.com/757075 Fix testbed-ap JetstreamHost detection.
        device_host = hosts.create_host(device_hostname,
                                        host_class=hosts.CrosHost,
                                        allow_failure=True)

        # Stop recover_duts now, for cases where we don't go through a full
        # update below.
        self.stop_recover_duts(device_host)

        # Remove un-wanted files to freeup diskspace before starting update.
        self.freeup_disk_space(device_host)
        self.update_device(device_host)

        # Stop recover_duts again, in case provisioning re-enabled it.
        self.stop_recover_duts(device_host)

    def update_device(self, device_host):
        """Update router and pcap associated with host.

        @param device_host: router / pcap host object
        @param device_board: router / pcap board name

        """
        device_board = device_host.get_board().split(':', 1)[1]
        desired = self.STABLE_VERSIONS.get(device_board, None)
        if desired is None:
            raise error.TestFail('No stable version found for %s with board=%s.'
                                 % (device_host.hostname, device_board))

        logging.info('Checking whether %s is at the latest stable version: %s',
                     device_host.hostname, desired.release_version)
        current_release_version = self.get_release_version(device_host)
        if desired.release_version == current_release_version:
            raise error.TestNAError('%s is already at latest version %s.' %
                                    (device_host.hostname,
                                     desired.release_version))

        logging.info('Updating %s to image %s from %s',
                     device_host.hostname, desired.release_version,
                     current_release_version)
        try:
            ds = dev_server.ImageServer.resolve(desired.builder_version,
                                                device_host.hostname)
        except dev_server.DevServerException as e:
            logging.error(e)
            raise error.TestFail(str(e))

        url = self.get_update_url(ds.url(), desired.builder_version)
        provisioner.ChromiumOSProvisioner(url,
                                          host=device_host).run_provision()
