# Copyright 2020 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.


"""The autotest performing FW update, both EC and AP in CCD mode."""
import logging

from autotest_lib.client.common_lib import error
from autotest_lib.server.cros.faft.cr50_test import Cr50Test
from autotest_lib.server.cros.servo import servo

MAX_TRIES=2


class firmware_Cr50CCDFirmwareUpdate(Cr50Test):
    """A test that can provision a machine to the correct firmware version."""

    version = 1
    should_restore_fw = False

    def initialize(self, host, cmdline_args, full_args):
        """Initialize the test and check if cr50 exists.

        Raises:
            TestNAError: If the dut is not proper for this test for its RDD
                         recognition problem.
        """
        super(firmware_Cr50CCDFirmwareUpdate,
              self).initialize(host, cmdline_args, full_args)

        # 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')

        servo_type = self.servo.get_servo_version()
        if 'ccd_cr50' not in servo_type:
            raise error.TestNAError('unsupported servo type: %s' % servo_type)

        if eval(full_args.get('backup_fw', 'False')):
            self.backup_firmware()

    def cleanup(self):
        try:
            if not self.should_restore_fw:
                return

            self.cr50.reboot()
            self.switcher.mode_aware_reboot(reboot_type='cold')

            # Verify the EC is responsive before raising an error and going to
            # cleanup. Repair and cleanup don't recover corrupted EC firmware
            # very well.
            try:
                self.verify_ec_response()
            except Exception as e:
                logging.error('Caught exception: %s', str(e))

            if self.is_firmware_saved():
                logging.info('Restoring firmware')
                self.restore_firmware()
            else:
                logging.info('chromeos-firmwareupdate --mode=recovery')
                result = self._client.run('chromeos-firmwareupdate'
                                          ' --mode=recovery',
                                          ignore_status=True)
                if result.exit_status != 0:
                    logging.error('chromeos-firmwareupdate failed: %s',
                                  result.stdout.strip())
                self._client.reboot()
        except Exception as e:
            logging.error('Caught exception: %s', str(e))
        finally:
            super(firmware_Cr50CCDFirmwareUpdate, self).cleanup()

    def verify_ec_response(self):
        """ Verify the EC is responsive."""
        # Try to reflash EC a couple of times to see if it's possible to recover
        # the device now.
        count = MAX_TRIES
        while True:
            try:
                if self.servo.get_ec_board():
                    return
            except servo.ConsoleError as e:
                logging.error('EC console is unresponsive: %s', str(e))

            if count == 0:
                break

            count -= 1
            # In the last iteration, try with main servo device.
            if count == 0:
                self.servo.enable_main_servo_device()

            try:
                self.cros_host.firmware_install(build=self.b_ver,
                                                install_bios=False)
            except Exception as e:
                logging.error('firmware_install failed: %s', str(e))

        logging.error('DUT likely needs a manual recovery.')

    def run_once(self, host, rw_only=False):
        """The method called by the control file to start the test.

        Args:
          host: a CrosHost object of the machine to update.
          rw_only: True to only update the RW firmware.

        Raises:
          TestFail: if the firmware version remains unchanged.
          TestError: if the latest firmware release cannot be located.
          TestNAError: if the test environment is not properly set.
                       e.g. the servo type doesn't support this test.
        """
        self.cros_host = host
        # Get the parent (a.k.a. reference board or baseboard), and hand it
        # to get_latest_release_version so that it
        # can use it in search as secondary candidate. For example, bob doesn't
        # have its own release directory, but its parent, gru does.
        parent = getattr(self.faft_config, 'parent', None)

        self.b_ver = host.get_latest_release_version(self.faft_config.platform,
                                                     parent)
        if not self.b_ver:
            raise error.TestError('Cannot locate the latest release for %s' %
                                  self.faft_config.platform)

        # Fast open cr50 and check if testlab is enabled.
        self.fast_ccd_open(enable_testlab=True)
        if self.servo.has_control('active_v4_device'):
            try:
                self.servo.set('active_v4_device', 'ccd_cr50')
            except error.TestFail as e:
                raise error.TestNAError('cannot change active_v4_device: %s' %
                                        str(e))

        # If it is ITE EC, then ccd reset factory.
        if self.servo.get('ec_chip') == 'it83xx':
            self.cr50.set_cap('I2C', 'Always')

        self.should_restore_fw = True
        try:
            self.cros_host.firmware_install(build=self.b_ver, rw_only=rw_only,
                                            dest=self.resultsdir,
                                            verify_version=True)
        except Exception as e:
            # The test failed to flash the firmware.
            raise error.TestFail('firmware_install failed with CCD: %s' %
                                 str(e))
