# Copyright 2020 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 logging
import xmlrpclib

from autotest_lib.client.common_lib import error
from autotest_lib.server.cros.faft.firmware_test import FirmwareTest


class firmware_FWupdateThenSleep(FirmwareTest):
    """Firmware update using chromeos-firmwareupdate --mode=recovery, then
    sleep and wake, then make sure the host responds and the flash contents
    don't change.
    """
    MODE = 'recovery'
    MIN_BATTERY_LEVEL = 20

    def initialize(self, host, cmdline_args, battery_only=False):

        self.flashed = False
        self._want_restore = None
        self._original_sw_wp = {}
        self._original_hw_wp = None

        super(firmware_FWupdateThenSleep, self).initialize(host, cmdline_args)

        ac_online = self._client.is_ac_connected()
        battery_percentage = self._client.get_battery_display_percentage()
        self.have_power_control = False
        if battery_only:
            if not self._client.has_battery():
                raise error.TestNAError("DUT type does not have a battery.")

            if self.servo.supports_built_in_pd_control():
                self.have_power_control = True
                self.setup_pdtester(False, True, False, min_batt_level=25)
            elif ac_online:
                raise error.TestNAError(
                    "For this version of the test, the DUT power supply must"
                    " be unplugged, or connected through Servo V4 Type-C.")
            elif battery_percentage < self.MIN_BATTERY_LEVEL:
                raise error.TestError(
                    "Battery level is too low (%s%%).  Please charge the DUT "
                    "to at least %s%%, then try again."
                    % (battery_percentage, self.MIN_BATTERY_LEVEL))
            else:
                logging.info("On battery: %s%% charge", battery_percentage)

        self._original_sw_wp = self.faft_client.bios.get_write_protect_status()
        self._original_hw_wp = 'on' in self.servo.get('fw_wp_state')

        self.backup_firmware()
        self.setup_firmwareupdate_shellball()

        if self.faft_config.ap_access_ec_flash:
            self._setup_ec_write_protect(False)
        self.set_hardware_write_protect(False)
        self.faft_client.bios.set_write_protect_range(0, 0, False)

        if battery_only and self.have_power_control:
            self.set_servo_v4_role_to_snk()

    def cleanup(self):
        """Restore the original firmware and original write-protect."""
        self._restore_servo_v4_role()

        self.set_hardware_write_protect(False)
        try:
            if self.flashed and self.is_firmware_saved():
                self.restore_firmware()
        except (EnvironmentError, xmlrpclib.Fault,
                error.AutoservError, error.TestBaseException):
            logging.error("Problem restoring firmware:", exc_info=True)

        try:
            # Restore the old write-protection value at the end of the test.
            if self._original_sw_wp:
                self.faft_client.bios.set_write_protect_range(
                        self._original_sw_wp['start'],
                        self._original_sw_wp['length'],
                        self._original_sw_wp['enabled'])
        except (EnvironmentError, xmlrpclib.Fault,
                error.AutoservError, error.TestBaseException):
            logging.error("Problem restoring SW write-protect:", exc_info=True)

        if self._original_hw_wp is not None:
            self.set_hardware_write_protect(self._original_hw_wp)

        super(firmware_FWupdateThenSleep, self).cleanup()

    def get_installed_versions(self):
        """Get the installed versions of BIOS and EC firmware.

        @return: A nested dict keyed by target ('bios' or 'ec') and then section
        @rtype: dict
        """
        versions = dict()
        versions['bios'] = self.faft_client.updater.get_device_fwids('bios')
        if self.faft_config.chrome_ec:
            versions['ec'] = self.faft_client.updater.get_device_fwids('ec')
        return versions

    def apply_update(self, append, before_fwids, image_fwids, wp=0):
        """Run chromeos-firmwareupdate with given sub-case

        @param append: additional piece to add to shellball name
        @param wp: is the flash write protected (--wp)?
        @return: a list of failure messages for the case
        """
        options = ['--wp=%s' % wp, '--quirks=ec_partial_recovery=0']

        if append:
            cmd_desc = ['chromeos-firmwareupdate-%s' % append]
        else:
            cmd_desc = ['chromeos-firmwareupdate']
        cmd_desc += ['--mode=%s' % self.MODE]
        cmd_desc += options
        cmd_desc = ' '.join(cmd_desc)

        expected_written = {}

        if wp:
            bios_written = ['a', 'b']
            ec_written = []  # EC write is all-or-nothing
        else:
            bios_written = ['ro', 'a', 'b']
            ec_written = ['ro', 'rw']

        expected_written['bios'] = bios_written

        if self.faft_config.chrome_ec and ec_written:
            expected_written['ec'] = ec_written

        # remove quotes and braces: bios: [a, b], ec: [ro, rw]
        written_desc = repr(expected_written).replace("'", "")[1:-1]
        logging.debug('Before(%s): %s', append or '', before_fwids)
        logging.debug('Image(%s):  %s', append or '', image_fwids)
        logging.info("Run %s (should write %s)", cmd_desc, written_desc)

        # make sure we restore firmware after the test, if it tried to flash.
        self.flashed = True

        errors = []
        result = self.run_chromeos_firmwareupdate(
                self.MODE, append, options, ignore_status=True)

        if result.exit_status == 255:
            logging.warn("DUT network dropped during update.")
        elif result.exit_status != 0:
            if (image_fwids == before_fwids and
                    'Good. It seems nothing was changed.' in result.stdout):
                logging.info("DUT already matched the image; updater aborted.")
            else:
                errors.append('...updater: unexpectedly failed (rc=%s)' %
                              result.exit_status)

        after_fwids = self.get_installed_versions()
        logging.debug('After(%s):  %s', append or '', after_fwids)

        errors += self.check_fwids_written(
                before_fwids, image_fwids, after_fwids, expected_written)

        if errors:
            logging.debug('%s', '\n'.join(errors))
            return ["%s (should write %s)\n%s"
                    % (cmd_desc, written_desc, '\n'.join(errors))]
        return []

    def run_once(self, wp=0, battery_only=False):
        """Try a firmware update, then put the machine in sleep and wake it."""

        errors = []
        original_boot_id = self._client.get_boot_id()

        have_ec = bool(self.faft_config.chrome_ec)
        before_fwids = self.get_installed_versions()

        self.modify_shellball('mod', modify_ro=True, modify_ec=have_ec)
        modded_fwids = self.identify_shellball(include_ec=have_ec)

        # Check power again, in case it got reconnected during setup.
        if battery_only and self._client.is_ac_connected():
            if self.have_power_control:
                raise error.TestError(
                    "DUT is on AC power, even though Servo role was set to"
                    " sink.  Is a second power supply connected?")
            else:
                raise error.TestError(
                    "DUT is back on AC power, when it should be on battery."
                    "  Did it get plugged back in?")

        errors += self.apply_update('mod', before_fwids, modded_fwids, wp=wp)
        if errors:
            fail_msg = "Problem(s) occurred during flash, before sleep:"
            errors.insert(0, fail_msg)
            raise error.TestFail('\n'.join(errors))

        logging.info("Firmware flashed successfully; trying sleep.")
        before_sleep_fwids = self.get_installed_versions()
        self.suspend()
        if self.faft_config.chrome_ec:
            if not self.wait_power_state(
                    self.POWER_STATE_SUSPEND, self.DEFAULT_PWR_RETRIES):
                raise error.TestFail('Platform failed to reach a suspend state'
                                     ' after flashing firmware.')
        else:
            self.switcher.wait_for_client_offline(orig_boot_id=original_boot_id)
        logging.info("System should now be in sleep; trying to wake.")

        self.servo.power_normal_press()
        self.switcher.wait_for_client()

        after_sleep_fwids = self.get_installed_versions()
        logging.debug('After sleep+wake:  %s', after_sleep_fwids)

        if have_ec:
            expected_changes = {'bios': None, 'ec': None}
        else:
            expected_changes = {'bios': None}

        after_sleep_errors = self.check_fwids_written(
                before_sleep_fwids, None, after_sleep_fwids, expected_changes)
        if after_sleep_errors:
            errors += ['After sleep, FWIDs unexpectedly differ from'
                       ' what was written:'] + after_sleep_errors

        if errors:
            fail_msg = "Problem(s) occurred during flash + sleep + wake:"
            errors.insert(0, fail_msg)
            raise error.TestFail('\n'.join(errors))
