# Copyright (c) 2012 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.client.common_lib.cros import cr50_utils
from autotest_lib.server.cros.faft.firmware_test import FirmwareTest
from autotest_lib.server.cros import vboot_constants as vboot


class firmware_SoftwareSync(FirmwareTest):
    """
    Servo based EC software sync test.
    """
    version = 1

    def initialize(self, host, cmdline_args, dev_mode=False):
        # This test tries to corrupt EC firmware. Should disable EC WP.
        super(firmware_SoftwareSync, self).initialize(host, cmdline_args,
                                                      ec_wp=False)

        # Don't bother if there is no Chrome EC.
        if not self.check_ec_capability():
            raise error.TestNAError("Nothing needs to be tested on this device")

        # 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')
        self.setup_usbkey(usbkey=False)
        self.setup_rw_boot()
        self.dev_mode = dev_mode

        if self.ec.check_feature('EC_FEATURE_EFS2'):
            self.original_ccd_level = self.cr50.get_ccd_level()

            # CCD needs to be open for 'ec_comm corrupt' run.
            self.fast_ccd_open(reset_ccd=False, dev_mode=dev_mode)
            logging.info("CCD opened.")
        else:
            self.original_ccd_level = None

        # Check for cr50 support on a device and get the boot mode. It should
        # be NORMAL at this point, even if EFS2 is not supported.
        if hasattr(self, 'cr50'):
            res = cr50_utils.GSCTool(host, ['-a', '-g']).stdout.strip()
            if 'NORMAL' in res:
                pass
            elif 'error' in res.lower():
                raise error.TestFail('TPM Vendor command GET_BOOT_MODE failed:'
                                    ' %r' % res)
            else:
                raise error.TestFail('GET_BOOT_MODE did not return NORMAL:'
                                     ' %r' % res)

    def cleanup(self):
        try:
            if self.is_firmware_saved():
                self.restore_firmware()
        except Exception as e:
            logging.error("Caught exception: %s", str(e))

        try:
            if self.original_ccd_level:
                self.cr50.set_ccd_level(self.original_ccd_level)
        except Exception as e:
            logging.error("Failed to restore ccd to %r: %s",
                          self.original_ccd_level, str(e))

        super(firmware_SoftwareSync, self).cleanup()

    def record_hash(self):
        """Record current EC hash."""
        self._ec_hash = self.faft_client.ec.get_active_hash()
        logging.info("Stored EC hash: %s", self._ec_hash)

    def corrupt_active_rw(self):
        """Corrupt the active RW portion."""
        section = 'rw'
        try:
            if self.servo.get_ec_active_copy() == 'RW_B':
                section = 'rw_b'
        except error.TestFail:
            # Skip the failure, as ec_active_copy is new.
            # TODO(waihong): Remove this except clause.
            pass
        logging.info("Corrupt the EC section: %s", section)
        self.faft_client.ec.corrupt_body(section)

    def software_sync_checker(self):
        """Check EC firmware is restored by software sync."""
        ec_hash = self.faft_client.ec.get_active_hash()
        logging.info("Current EC hash: %s", ec_hash)
        if self._ec_hash != ec_hash:
            return False
        return self.checkers.ec_act_copy_checker('RW')

    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_test_corrupt_ec_rw(self):
        """Runs a single iteration of the test."""
        logging.info("Corrupt EC firmware RW body.")
        self.check_state((self.checkers.ec_act_copy_checker, 'RW'))
        self.record_hash()
        self.corrupt_active_rw()
        logging.info("Reboot AP, check EC hash, and software sync it.")
        self.switcher.simple_reboot(reboot_type='warm')
        self.wait_software_sync_and_boot()
        self.switcher.wait_for_client()

        logging.info("Expect EC in RW and RW is restored.")
        self.check_state(self.software_sync_checker)

    def run_test_corrupt_hash_in_cr50(self):
        """Run the test corrupting ECRW hash in CR50."""

        self.check_state((self.checkers.ec_act_copy_checker, 'RW'))
        self.record_hash()

        logging.info('Corrupt ECRW hashcode in TPM kernel NV index.')
        ec_corrupt_cmd = 'ec_comm corrupt'
        self.cr50.send_command(ec_corrupt_cmd)

        try:
            # Reboot EC but keep AP off, so that it can earn a time to check
            # if boot_mode is NO_BOOT and EC is in RO.
            logging.info('Reset EC with AP off.')
            self.ec.reboot('ap-off')
            time.sleep(5)

            # The boot mode should be "NO_BOOT".
            logging.info('Check the boot mode is NO_BOOT mode.')
            if not self.cr50.check_boot_mode('NO_BOOT'):
                raise error.TestFail('Boot mode is not NO_BOOT.')

            # Check if the current EC image is RO.
            logging.info('Check EC is in RO.')
            if not self.ec.check_ro_rw('RO'):
                raise error.TestFail('EC is not in RO mode.')
        finally:
            # Wake up AP by tapping power button.
            logging.info('Wake up AP.')
            self.servo.power_short_press()

        # Wait for software sync is done.
        self.wait_software_sync_and_boot()
        self.switcher.wait_for_client()

        # The boot mode should be "NORMAL".
        logging.info('Check the boot mode is NORMAL mode.')
        if not self.cr50.check_boot_mode('NORMAL'):
            logging.warn('You may want to run %r in cr50 console to uncorrupt'
                         ' EC hash.', ec_corrupt_cmd)
            raise error.TestFail('Boot mode is not NORMAL.')

        logging.info('Expect EC in RW and RW is restored.')
        self.check_state(self.software_sync_checker)

    def run_once(self):
        """Entry point of this test."""
        self.run_test_corrupt_ec_rw()

        if self.ec.check_feature('EC_FEATURE_EFS2'):
            self.run_test_corrupt_hash_in_cr50()
