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


""" The autotest performing Cr50 update."""


import os
import logging

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


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

    Take value and split it into image_rw_ver, image_bid, and chip bid if it
    is specifying a prod signed image. If it requests a selfsigned image split
    it into the dev server build info and chip board id.

    Update Cr50 so it is running the correct image with the right chip baord id.

    value=prodsigned-0.0.23(/ZZAF:ffffffff:7f00/ZZAF:7f80)?
    value=selfsigned-reef-release/R61-9704.0.0(/ZZAF:7f80)?

    """

    version = 1

    def initialize(self, host, cmdline_args, full_args, value='',
                   release_path='', chip_bid_str=''):
        """Initialize get the cr50 update version information"""
        super(provision_Cr50Update, self).initialize(host, cmdline_args,
            full_args, provision_update=True)
        # TODO(mruthven): remove once the test is successfully scheduled.
        logging.info('SUCCESSFULLY SCHEDULED PROVISION CR50 UPDATE with %r',
                     value)
        return
        self.host = host
        self.chip_bid_str = chip_bid_str

        image_info = None

        if os.path.isfile(release_path):
            image_info = self.get_local_image(release_path)
        else:
            source, test_info = value.split('-', 1)

            # The chip board id is optional so value can be
            # 'ver_part_1/ver_part_2/chip_bid' or 'ver_part_1/ver_part_2'.
            #
            # Get the chip bid from test_info if it was included.
            if test_info.count('/') == 2:
                test_info, self.chip_bid_str = test_info.rsplit('/', 1)

            if source == 'prodsigned':
                image_info = self.get_prodsigned_image(test_info)
            if source == 'selfsigned':
                image_info = self.get_selfsigned_image(test_info)

        if not image_info:
            raise error.TestError('Could not find new cr50 image')

        self.local_path, self.image_ver = image_info
        self.image_rw = self.image_ver[1]
        self.image_bid = self.image_ver[2]


    def get_local_image(self, release_path):
        """Get the version of the local image.

        Args:
            release_path: The local path to the cr50 image

        Returns:
            the local path, image version tuple
        """
        ver = cr50_utils.InstallImage(self.host, release_path,
            '/tmp/release.bin')[1]
        return release_path, ver


    def get_prodsigned_image(self, value):
        """Find the release image.

        Args:
            value: The Cr50 image version info rw_ver/image_bid. The image_bid
                   is optional

        Returns:
            the local path, image version tuple
        """
        release_bid_str = None
        values = value.split('/')
        release_ver = values[0]

        if len(values) > 1 and values[1]:
            release_bid_str = values[1]

        return self.download_cr50_release_image(release_ver,
            release_bid_str)


    def get_selfsigned_image(self, value):
        """Find the selfsigned image image.

        The value should be something like reef-release/R61-9704.0.0

        Args:
            value: A string with the build to extract the cr50 image from.

        Returns:
            the local path, image version tuple

        Raises:
            TestError because it is not yet implemented
        """
        # TODO(mruthven): Add support for downloading the image from the
        # devserver and extracting the cr50 image.
        raise error.TestError('No support for finding %s', value)


    def check_bid_settings(self, chip_bid_info, image_bid_str):
        """Compare the chip and image board ids.

        Compare the image and chip board ids before changing the cr50 state.
        Raise an error if the image will not be able to run with the requested
        chip board id.

        Args:
            chip_bid_info: The chip board id info tuple
            image_bid_str: the image board_id:mask:flags.

        Raises:
            TestFail if we will not be able to update to the image with the
            given chip board id.
        """
        # If the image isn't board id locked, it will run on all devices.
        if chip_bid_info == cr50_utils.ERASED_CHIP_BID:
            logging.info('Chip has no board id. It will run any image.')
            return
        if not image_bid_str:
            logging.info('Image is not board id locked. It will run on all '
                         'devices.')
            return

        chip_bid, chip_bid_inv, chip_flags = chip_bid_info
        chip_bid_str = cr50_utils.GetBoardIdInfoString(chip_bid_info,
            symbolic=True)

        image_bid, image_mask, image_flags = image_bid_str.split(':')

        # Convert the image board id to integers
        image_mask = int(image_mask, 16)
        image_bid = cr50_utils.GetIntBoardId(image_bid)
        image_flags = int(image_flags, 16)

        errors = []
        # All bits in the image mask must match between the image and chip board
        # ids.
        image_bid = image_bid & image_mask
        chip_bid = chip_bid & image_mask
        if image_bid != chip_bid:
            errors.append('board id')
        # All 1s in the image flags must also be 1 in the chip flags
        chip_flags = chip_flags & image_flags
        if image_flags != chip_flags:
            errors.append('flags')
        if len(errors):
            raise error.TestFail('Image will not be able to run with the '
                'given %s: chip %s image %s' % (' and '.join(errors),
                chip_bid_str, image_bid_str))


    def get_new_chip_bid(self):
        """Get the new chip board id and flags.

        Returns:
            a tuple chip bid info, a bool True if the chip board id needs to
            change.
        """
        chip_bid_info = self.chip_bid_str.split(':')
        running_bid_info = cr50_utils.GetChipBoardId(self.host)

        # If no board id was specified, restore the original board id
        if len(chip_bid_info) != 2 or not chip_bid_info[0]:
            logging.info('No board id given. Using the current chip settings '
                         '%s', running_bid_info)
            return running_bid_info, False

        chip_bid = cr50_utils.GetIntBoardId(chip_bid_info[0])
        chip_flags = int(chip_bid_info[1], 16)

        chip_bid_info = (chip_bid, 0xffffffff ^ chip_bid, chip_flags)
        set_bid = chip_bid_info != running_bid_info
        return chip_bid_info, set_bid


    def check_final_state(self, chip_bid_info):
        """Verify the update checking the chip board id and running image

        Args:
            chip_bid_info: A tuple of ints: chip_board_id, ~chip_board_id,
                           and flags.

        Raises:
            TestFail if the device did not update to the correct state
        """
        state = self.get_cr50_device_state()
        image_bid = cr50_utils.GetBoardIdInfoString(self.image_bid)

        failed = []
        if chip_bid_info != state['chip_bid']:
            failed.append('cr50 chip board id')
        if image_bid != state['running_image_bid']:
            failed.append('cr50 image board id')
        if self.image_rw != state['running_image_ver'][1]:
            failed.append('cr50 image version')
        if self.image_ver != state['device_prod_ver']:
            failed.append('device prod image')
        if self.image_ver != state['device_prepvt_ver']:
            failed.append('device prepvt image')
        if len(failed):
            raise error.TestFail('Update failures: %s', ', '.join(failed))


    def run_once(self):
        """The method called by the control file to start the update."""
        # TODO(mruthven): remove once the test is successfully scheduled.
        logging.info('skipping update')
        return
        chip_bid_info, set_bid = self.get_new_chip_bid()

        logging.info('Updating to image %s with chip board id %s',
            self.image_ver, cr50_utils.GetBoardIdInfoString(chip_bid_info))

        # Make sure the image will be able to run with the given chip board id.
        self.check_bid_settings(chip_bid_info, self.image_bid)

        # If the release version is not newer than the running rw version, we
        # have to do a rollback.
        running_rw = cr50_utils.GetRunningVersion(self.host)[1]
        rollback = (cr50_utils.GetNewestVersion(running_rw, self.image_rw) !=
            self.image_rw)

        # You can only update the board id or update to an old image by rolling
        # back from a dev image.
        need_rollback = rollback or set_bid
        if need_rollback and not self.has_saved_dbg_image_path():
            raise error.TestFail('Need a dev image to rollback to %s or update'
                                 'the board id')
        # Copy the image onto the DUT. cr50-update uses both cr50.bin.prod and
        # cr50.bin.prepvt in /opt/google/cr50/firmware/, so copy it to both
        # places. Rootfs verification has to be disabled to do the copy.
        filesystem_util.make_rootfs_writable(self.host)
        cr50_utils.InstallImage(self.host, self.local_path,
                cr50_utils.CR50_PREPVT)
        cr50_utils.InstallImage(self.host, self.local_path,
                cr50_utils.CR50_PROD)

        # Update to the dev image if there needs to be a rollback.
        if need_rollback:
            self.cr50_update(self.get_saved_dbg_image_path())

        # If we aren't changing the board id, don't pass any values into the bid
        # args.
        chip_bid = chip_bid_info[0] if need_rollback else None
        chip_flags = chip_bid_info[2] if need_rollback else None
        # Update to the new image, setting the chip board id and rolling back if
        # necessary.
        self.cr50_update(self.local_path, rollback=need_rollback,
            chip_bid=chip_bid, chip_flags=chip_flags)

        cr50_utils.ClearUpdateStateAndReboot(self.host)

        # Verify everything updated correctly
        self.check_final_state(chip_bid_info)
