# 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_dut_controller'):
            try:
                self.servo.set('active_dut_controller', '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))
