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

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


class firmware_FWupdateWP(FirmwareTest):
    """RO+RW firmware update using chromeos-firmware, with WP=1 and with WP=0.
    It modifies the FWIDs of the current firmware before flashing, and restores
    the firmware after the test.
    """

    # Region to use for flashrom wp-region commands
    WP_REGION = 'WP_RO'
    MODE = 'recovery'

    def initialize(self, host, cmdline_args):

        self.flashed = False

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

        self._old_bios_wp = self.faft_client.bios.get_write_protect_status()

        stripped_bios = self.faft_client.bios.strip_modified_fwids()
        if stripped_bios:
            logging.warn(
                    "Fixed the previously modified BIOS FWID(s): %s",
                    stripped_bios)

        if self.faft_config.chrome_ec:
            stripped_ec = self.faft_client.ec.strip_modified_fwids()
            if stripped_ec:
                logging.warn(
                        "Fixed the previously modified EC FWID(s): %s",
                        stripped_ec)

        self.backup_firmware()

        self.set_ap_write_protect_and_reboot(False)
        self.faft_client.bios.set_write_protect_region(self.WP_REGION, True)
        self.set_ap_write_protect_and_reboot(True)

    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
        """
        vers = dict()
        vers['bios'] = self.faft_client.updater.get_device_fwids('bios')
        if self.faft_config.chrome_ec:
            vers['ec'] = self.faft_client.updater.get_device_fwids('ec')
        return vers

    def run_case(self, append, write_protected, before_fwids, image_fwids):
        """Run chromeos-firmwareupdate with given sub-case

        @param append: additional piece to add to shellball name
        @param write_protected: is the flash write protected (--wp)?
        @param before_fwids: fwids before flashing ('bios' and 'ec' as keys)
        @param image_fwids: fwids in image ('bios' and 'ec' as keys)
        @return: a list of failure messages for the case
        """

        cmd_desc = ('chromeos-firmwareupdate --mode=%s [wp=%s]'
                    % (self.MODE, write_protected))

        # Unlock the protection of the wp-enable and wp-range registers
        self.set_ap_write_protect_and_reboot(False)

        if write_protected:
            self.faft_client.bios.set_write_protect_region(self.WP_REGION, True)
            self.set_ap_write_protect_and_reboot(True)
        else:
            self.faft_client.bios.set_write_protect_region(
                    self.WP_REGION, False)

        expected_written = {}

        if write_protected:
            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

        # bios: [a, b], ec: [ro, rw]
        written_desc = repr(expected_written).replace("'", "")[1:-1]
        logging.debug('Before(%s): %s', append, before_fwids)
        logging.debug('Image(%s):  %s', append, 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 = []
        options = ['--quirks=ec_partial_recovery=0']
        result = self.run_chromeos_firmwareupdate(
                self.MODE, append, options, ignore_status=True)

        if result.exit_status == 255:
            logging.info("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, 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))]
        else:
            return []

    def run_once(self, host):
        """Run chromeos-firmwareupdate with recovery or factory mode.

        @param host: host to run on
        """
        append = 'new'
        have_ec = bool(self.faft_config.chrome_ec)

        self.faft_client.updater.extract_shellball()

        before_fwids = self.get_installed_versions()

        # Modify the stock image
        logging.info(
                "Using the currently running firmware, with modified fwids")
        self.setup_firmwareupdate_shellball()
        self.faft_client.updater.reload_images()
        self.modify_shellball(append, modify_ro=True, modify_ec=have_ec)
        modded_fwids = self.identify_shellball(include_ec=have_ec)

        fail_msg = "Section contents didn't show the expected changes."

        errors = []
        # no args specified, so check both wp=1 and wp=0
        errors += self.run_case(append, 1, before_fwids, modded_fwids)
        errors += self.run_case(append, 0, before_fwids, modded_fwids)

        if errors:
            raise error.TestFail("%s\n%s" % (fail_msg, '\n'.join(errors)))

    def cleanup(self):
        """
        Restore firmware from the backup taken before flashing.
        No EC reboot is needed, because the test doesn't actually reboot the EC
        with the "new" firmware.
        """
        self.set_ap_write_protect_and_reboot(False)
        self.faft_client.bios.set_write_protect_range(0, 0, False)

        if self.flashed:
            logging.info("Restoring firmware")
            self.restore_firmware()

        # Restore the old write-protection value at the end of the test.
        self.faft_client.bios.set_write_protect_range(
                self._old_bios_wp['start'],
                self._old_bios_wp['length'],
                self._old_bios_wp['enabled'])

        super(firmware_FWupdateWP, self).cleanup()
