# Copyright 2017 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 time

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


class firmware_ECUpdateId(FirmwareTest):
    """
    Servo based EC test for updating EC ID for verifying EC EFS.
    """
    version = 1

    def initialize(self, host, cmdline_args, dev_mode=False):
        # If EC isn't write-protected, it won't do EFS. Should enable WP.
        super(firmware_ECUpdateId, self).initialize(host, cmdline_args,
                                                    ec_wp=True)
        # Don't bother if there is no Chrome EC or if the EC is non-EFS.
        if not self.check_ec_capability():
            raise error.TestNAError("Nothing needs to be tested on this device")
        if not self.faft_client.Ec.IsEfs():
            raise error.TestNAError("Nothing needs to be tested for non-EFS")
        # In order to test software sync, it must be enabled.
        self.clear_set_gbb_flags(vboot.GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC, 0)
        self.backup_firmware()
        self.switcher.setup_mode('dev' if dev_mode else 'normal')
        # It makes updater-related RPCs to use the active AP/EC firmware,
        # instead of the firmware in the shellball.
        self.setup_firmwareupdate_shellball()
        self.setup_usbkey(usbkey=False)
        self.setup_rw_boot()
        self.setup_ec_rw_to_a()
        self.dev_mode = dev_mode

    def cleanup(self):
        # The superclass's cleanup() restores the original WP state.
        # Do it before restore the firmware.
        super(firmware_ECUpdateId, self).cleanup()
        try:
            if self.is_firmware_saved():
                self.restore_firmware()
        except Exception as e:
            logging.error("Caught exception: %s", str(e))

    def setup_ec_rw_to_a(self):
        """For EC EFS, make EC boot into RW A."""
        if self.faft_client.Ec.IsEfs():
            active_copy = self.servo.get_ec_active_copy()
            if active_copy == 'RW_B':
                from_section = 'rw_b'
                to_section = 'rw'
                logging.info("Copy EC RW from '%s' to '%s'",
                             from_section, to_section)
                self.faft_client.Ec.CopyRw(from_section, to_section)

                logging.info("EC reboot to switch slot. Wait DUT up...")
                reboot = lambda: self.faft_client.Ec.RebootToSwitchSlot()
                self.switcher.mode_aware_reboot('custom', reboot)

    def get_active_hash(self):
        """Return the current EC hash."""
        ec_hash = self.faft_client.Ec.GetActiveHash()
        logging.info("Current EC hash: %s", ec_hash)
        return ec_hash

    def active_hash_checker(self, expected_hash):
        """Check if the current EC hash equals to the given one."""
        ec_hash = self.get_active_hash()
        result = ec_hash == expected_hash
        if not result:
            logging.info("Expected EC hash %s but now %s",
                         expected_hash, ec_hash)
        return result

    def active_copy_checker(self, expected_copy):
        """Check if the EC active copy is matched."""
        # Get the active copy via servod (EC console).
        # The result of crossystem doesn't reflect RW_B.
        active_copy = self.servo.get_ec_active_copy()
        result = active_copy == expected_copy
        if not result:
            logging.info("Expected EC in %s but now in %s",
                         expected_copy, active_copy)
        return result

    def corrupt_active_rw(self):
        """Corrupt the active RW portion."""
        section = 'rw'
        if self.servo.get_ec_active_copy() == 'RW_B':
            section = 'rw_b'
        logging.info("Corrupt the EC section: %s", section)
        self.faft_client.Ec.CorruptBody(section)

    def wait_software_sync_and_boot(self):
        """Wait for software sync to update EC."""
        if self.dev_mode:
            time.sleep(self.faft_config.software_sync_update +
                       self.faft_config.firmware_screen)
            self.servo.ctrl_d()
        else:
            time.sleep(self.faft_config.software_sync_update)

    def run_once(self):
        """Execute the main body of the test.
        """
        logging.info("Check the current state and record hash.")
        self.check_state((self.active_copy_checker, 'RW'))
        original_hash = self.get_active_hash()

        logging.info("Modify EC ID and flash it back to BIOS...")
        self.faft_client.Updater.ModifyEcidAndFlashToBios()
        modified_hash = self.faft_client.Updater.GetEcHash()

        logging.info("Reboot EC. Verify if EFS works as intended.")
        self.sync_and_ec_reboot('hard')
        self.wait_software_sync_and_boot()
        self.switcher.wait_for_client()

        logging.info("Expect EC in another RW slot (the modified hash).")
        self.check_state((self.active_copy_checker, 'RW_B'))
        self.check_state((self.active_hash_checker, modified_hash))

        logging.info("Disable EC WP (also reboot)")
        self.switcher.mode_aware_reboot(
                'custom',
                lambda:self.set_ec_write_protect_and_reboot(False))

        logging.info("Corrupt the active EC RW.")
        self.corrupt_active_rw()

        logging.info("Re-enable EC WP (also reboot)")
        self.switcher.mode_aware_reboot(
                'custom',
                lambda:self.set_ec_write_protect_and_reboot(True))

        logging.info("Expect EC recovered.")
        # * EC performs EC-EFS, jumps to A, and boots AP.
        # * AP software-sync's to EC B. Reboots.
        # * EC performs EC-EFS and jumps to B.
        self.check_state((self.active_copy_checker, 'RW_B'))
        self.check_state((self.active_hash_checker, modified_hash))

        logging.info("Restore the original AP firmware and reboot.")
        self.restore_firmware(restore_ec=False)

        logging.info("Expect EC restored back (the original hash).")
        # * EC performs EC-EFS, jumps to B, and boots AP.
        # * AP software-sync's to EC A. Reboots.
        # * EC performs EC-EFS and jumps to A.
        self.check_state((self.active_copy_checker, 'RW'))
        self.check_state((self.active_hash_checker, original_hash))
