# Copyright 2019 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
from autotest_lib.server.cros.faft.firmware_test import ConnectionError


class firmware_UpdaterModes(FirmwareTest):
    """RO+RW firmware update using chromeos-firmwareupdate with various modes.

    This test uses --emulate, to avoid writing repeatedly to the flash.
    """

    version = 1

    SHELLBALL = '/usr/sbin/chromeos-firmwareupdate'

    def initialize(self, host, cmdline_args, ec_wp=None):
        """
        During initialization, back up the firmware, in case --emulate ever
        breaks in a way that causes real writes.
        """
        super(firmware_UpdaterModes, self).initialize(host, cmdline_args, ec_wp)
        self.backup_firmware()

    def cleanup(self):
        """Restore the original firmware, if it was somehow overwritten."""
        try:
            if self.is_firmware_saved():
                self.restore_firmware()
        except ConnectionError:
            logging.error("ERROR: DUT did not come up after firmware restore!")
        finally:
            super(firmware_UpdaterModes, self).cleanup()

    def get_bios_fwids(self, path):
        """Return the BIOS fwids for the given file"""
        return self.faft_client.updater.get_image_fwids('bios', path)

    def run_case(self, mode, write_protected, written, modify_ro=True,
            should_abort=False, writes_gbb=False):
        """Run chromeos-firmwareupdate with given sub-case

        @param mode: factory or recovery or autoupdate
        @param write_protected: is the flash write protected (--wp)?
        @param modify_ro: should ro fwid be modified?
        @param written: list of bios areas expected to change
        @param should_abort: if True, the updater should abort with no changes
        @param writes_gbb: if True, the updater should rewrite gbb flags.
        @return: a list of failure messages for the case
        """
        self.faft_client.updater.reset_shellball()

        fake_bios_path = self.faft_client.updater.copy_bios('fake-bios.bin')
        self.faft_client.updater.set_image_gbb_flags(0, fake_bios_path)

        before_fwids = {'bios': self.get_bios_fwids(fake_bios_path)}
        before_gbb = self.faft_client.updater.get_image_gbb_flags(
                fake_bios_path)

        case_desc = ('chromeos-firmwareupdate --mode=%s --wp=%s'
                     % (mode, write_protected))

        if modify_ro:
            append = 'ro+rw'
        else:
            case_desc += ' [rw-only]'
            append = 'rw'

        # Repack the shellball with modded fwids
        self.modify_shellball(append, modify_ro)
        modded_fwids = self.identify_shellball()
        image_gbb = self.faft_client.updater.get_image_gbb_flags()

        options = ['--emulate', fake_bios_path, '--wp=%s' % write_protected]

        logging.info("%s (should write %s)", case_desc,
                     ', '.join(written).upper() or 'nothing')

        errors = []
        result = self.run_chromeos_firmwareupdate(mode, append, options,
                                                  ignore_status=True)
        if result.exit_status == 0:
            if should_abort:
                errors.append(
                        "...updater: with current mode and write-protect value,"
                        " should abort (rc!=0) and not modify anything")
        else:
            if should_abort:
                logging.debug('updater aborted as expected')
            else:
                errors.append('...updater: unexpectedly failed (rc!=0)')

        after_fwids = {'bios': self.get_bios_fwids(fake_bios_path)}
        after_gbb = self.faft_client.updater.get_image_gbb_flags(fake_bios_path)
        expected_written = {'bios': written or []}

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

        if not errors:
            logging.debug('...bios versions correct: %s', after_fwids['bios'])

        if writes_gbb:
            if after_gbb != image_gbb:
                # Expect rewritten, but it might not be different from before
                errors.append(
                        "...GBB flags weren't rewritten to match the image: "
                        "before=0x%x, image=0x%x, after=0x%x."
                        % (before_gbb, image_gbb, after_gbb))
        else:
            if after_gbb != before_gbb:
                errors.append(
                        "...GBB flags were unexpectedly rewritten: "
                        "before=0x%x, image=0x%x, after=0x%x."
                        % (before_gbb, image_gbb, after_gbb))

        if self.restore_firmware():
            # If real writes happen, fail immediately to avoid flash wear.
            raise error.TestFail(
                    'With chromeos-firmwareupdate --emulate, real flash device '
                    'was unexpectedly modified.')

        if errors:
            case_message = '%s:\n%s' % (case_desc, '\n'.join(errors))
            logging.error('%s', case_message)
            return [case_message]
        return []

    def run_once(self, host):
        """Run test, iterating through combinations of mode and write-protect"""
        errors = []

        # TODO(dgoyette): Add a test that checks EC versions (can't be emulated)

        # factory: update A, B, and RO; reset gbb flags.  If WP=1, abort.
        errors += self.run_case('factory', 0, ['ro', 'a', 'b'], writes_gbb=True)
        errors += self.run_case('factory', 1, [], should_abort=True)

        # recovery: update A and B, and RO if WP=0.
        errors += self.run_case('recovery', 0, ['ro', 'a', 'b'])
        errors += self.run_case('recovery', 1, ['a', 'b'])

        # autoupdate with changed ro: same as recovery (modify ro only if WP=0)
        errors += self.run_case('autoupdate', 0, ['ro', 'a', 'b'])
        errors += self.run_case('autoupdate', 1, ['b'])

        # autoupdate with unchanged ro: update inactive slot
        errors += self.run_case('autoupdate', 0, ['b'], modify_ro=False)
        errors += self.run_case('autoupdate', 1, ['b'], modify_ro=False)

        if len(errors) == 1:
            raise error.TestFail(errors[0])
        elif errors:
            raise error.TestFail(
                    '%s combinations of mode and write-protect failed:\n%s' %
                    (len(errors), '\n'.join(errors)))
