# Copyright (c) 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

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


class firmware_RecoveryCacheBootKeys(FirmwareTest):
    """
    This test ensures that when booting to recovery mode the device will use the
    cache instead training memory every boot.
    """
    version = 1
    NEEDS_SERVO_USB = True

    # Message in older mrc_cache driver code
    USED_CACHE_MSG1 = ('MRC: Hash comparison successful. '
                       'Using data from RECOVERY_MRC_CACHE')
    # Message in newer mrc_cache driver code
    USED_CACHE_MSG2 = ('MRC: Hash idx 0x100b comparison successful.')
    REBUILD_CACHE_MSG = "MRC: cache data 'RECOVERY_MRC_CACHE' needs update."
    RECOVERY_CACHE_SECTION = 'RECOVERY_MRC_CACHE'
    FIRMWARE_LOG_CMD = 'cbmem -1' + ' | grep ' + REBUILD_CACHE_MSG[:3]
    RECOVERY_REASON_REBUILD_CMD = 'crossystem recovery_request=0xC4'

    def initialize(self, host, cmdline_args, dev_mode=False):
        super(firmware_RecoveryCacheBootKeys, self).initialize(
                host, cmdline_args)

        if not self.faft_config.rec_force_mrc:
            raise error.TestNAError('DUT cannot force memory training.')

        self.client = host
        self.dev_mode = dev_mode
        self.switcher.setup_mode('dev' if dev_mode else 'normal',
                                 allow_gbb_force=True)
        self.setup_usbkey(usbkey=True, host=False)

    def cleanup(self):
        super(firmware_RecoveryCacheBootKeys, self).cleanup()
        self.switcher.simple_reboot()

    def boot_to_recovery(self, rebuild_mrc_cache=False):
        """Boots the device into recovery mode."""
        if rebuild_mrc_cache:
            self.switcher.reboot_to_mode(to_mode='rec_force_mrc')
        else:
            self.switcher.reboot_to_mode(to_mode='rec')

        self.check_state((self.checkers.crossystem_checker, {
                'mainfw_type': 'recovery'
        }))

    def cache_exist(self):
        """Checks the firmware log to ensure that the recovery cache exists.

        @return True if cache exists
        """
        logging.info("Checking if device has RECOVERY_MRC_CACHE")

        # If flashrom can read the section, this means it exists.
        command = ('flashrom -p host -r -i %s:/dev/null'
                   % self.RECOVERY_CACHE_SECTION)

        return self.faft_client.system.run_shell_command_check_output(
            command, 'SUCCESS')

    def check_cache_used(self):
        """Checks the firmware log to ensure that the recovery cache was used
        during recovery boot.

        @return True if cache used
        """
        logging.info('Checking if cache was used.')

        return (self.faft_client.system.run_shell_command_check_output(
                self.FIRMWARE_LOG_CMD, self.USED_CACHE_MSG1)
                or self.faft_client.system.run_shell_command_check_output(
                        self.FIRMWARE_LOG_CMD, self.USED_CACHE_MSG2))

    def check_cache_rebuilt(self):
        """Checks the firmware log to ensure that the recovery cache was rebuilt
        during recovery boot.

        @return True if cache rebuilt
        """
        logging.info('Checking if cache was rebuilt.')

        return self.faft_client.system.run_shell_command_check_output(
                self.FIRMWARE_LOG_CMD, self.REBUILD_CACHE_MSG)

    def run_once(self):
        """Runs a single iteration of the test."""
        if not self.cache_exist():
            raise error.TestNAError('No RECOVERY_MRC_CACHE was found on DUT.')

        logging.info('Ensure we\'ve done memory training.')
        self.boot_to_recovery()

        # With EFS, when the EC is in RO and we do a recovery boot, it
        # causes the EC to do a soft reboot, which will in turn cause
        # a PMIC reset (double reboot) on SKL/KBL power architectures.
        # This causes us to lose the request to do MRC training for
        # this test.  The solution is to make sure that the EC is in
        # RW before doing a recovery boot to ensure that the double
        # reboot does not occur and information/requests are not lost.
        self.switcher.simple_reboot('cold')

        logging.info('Checking recovery boot.')
        self.boot_to_recovery()

        if not self.check_cache_used():
            raise error.TestFail('Recovery Cache was not used.')

        self.switcher.simple_reboot('cold')

        logging.info('Checking recovery boot with forced MRC cache training.')
        self.boot_to_recovery(rebuild_mrc_cache=True)
        self.switcher.wait_for_client()

        if not self.check_cache_rebuilt():
            raise error.TestFail('Recovery Cache was not rebuilt.')

        logging.info('Reboot out of Recovery')
        self.switcher.simple_reboot()
