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

"""A module to support automatic firmware update.

See FirmwareUpdater object below.
"""

import os
import re

from autotest_lib.client.common_lib.cros import chip_utils
from autotest_lib.client.cros.faft.utils import (common,
                                                 flashrom_handler,
                                                 saft_flashrom_util,
                                                 shell_wrapper)


class FirmwareUpdaterError(Exception):
    """Error in the FirmwareUpdater module."""


class FirmwareUpdater(object):
    """An object to support firmware update.

    This object will create a temporary directory in /var/tmp/faft/autest with
    two subdirectory keys/ and work/. You can modify the keys in keys/
    directory. If you want to provide a given shellball to do firmware update,
    put shellball under /var/tmp/faft/autest with name chromeos-firmwareupdate.
    """

    DAEMON = 'update-engine'
    CBFSTOOL = 'cbfstool'
    HEXDUMP = 'hexdump -v -e \'1/1 "0x%02x\\n"\''

    def __init__(self, os_if):
        self.os_if = os_if
        self._temp_path = '/var/tmp/faft/autest'
        self._cbfs_work_path = os.path.join(self._temp_path, 'cbfs')
        self._keys_path = os.path.join(self._temp_path, 'keys')
        self._work_path = os.path.join(self._temp_path, 'work')
        self._bios_path = 'bios.bin'
        self._ec_path = 'ec.bin'
        pubkey_path = os.path.join(self._keys_path, 'root_key.vbpubk')
        self._bios_handler = common.LazyInitHandlerProxy(
                flashrom_handler.FlashromHandler,
                saft_flashrom_util,
                os_if,
                pubkey_path,
                self._keys_path,
                'bios')
        self._ec_handler = common.LazyInitHandlerProxy(
                flashrom_handler.FlashromHandler,
                saft_flashrom_util,
                os_if,
                pubkey_path,
                self._keys_path,
                'ec')

        # _detect_image_paths always needs to run during initialization
        # or after extract_shellball is called.
        #
        # If we are setting up the temp dir from scratch, we'll transitively
        # call _detect_image_paths since extract_shellball is called.
        # Otherwise, we need to scan the existing temp directory.
        if not self.os_if.is_dir(self._temp_path):
            self._setup_temp_dir()
        else:
            self._detect_image_paths()

    def _setup_temp_dir(self):
        """Setup temporary directory.

        Devkeys are copied to _key_path. Then, shellball (default:
        /usr/sbin/chromeos-firmwareupdate) is extracted to _work_path.
        """
        self.cleanup_temp_dir()

        self.os_if.create_dir(self._temp_path)
        self.os_if.create_dir(self._cbfs_work_path)
        self.os_if.create_dir(self._work_path)
        self.os_if.copy_dir('/usr/share/vboot/devkeys', self._keys_path)

        original_shellball = '/usr/sbin/chromeos-firmwareupdate'
        working_shellball = os.path.join(self._temp_path,
                                         'chromeos-firmwareupdate')
        self.os_if.copy_file(original_shellball, working_shellball)
        self.extract_shellball()

    def cleanup_temp_dir(self):
        """Cleanup temporary directory."""
        if self.os_if.is_dir(self._temp_path):
            self.os_if.remove_dir(self._temp_path)

    def stop_daemon(self):
        """Stop update-engine daemon."""
        self.os_if.log('Stopping %s...' % self.DAEMON)
        cmd = 'status %s | grep stop || stop %s' % (self.DAEMON, self.DAEMON)
        self.os_if.run_shell_command(cmd)

    def start_daemon(self):
        """Start update-engine daemon."""
        self.os_if.log('Starting %s...' % self.DAEMON)
        cmd = 'status %s | grep start || start %s' % (self.DAEMON, self.DAEMON)
        self.os_if.run_shell_command(cmd)

    def retrieve_fwid(self):
        """Retrieve shellball's fwid tuple.

        This method should be called after _setup_temp_dir.

        Returns:
            Shellball's fwid tuple (ro_fwid, rw_fwid).
        """
        self._bios_handler.new_image(
                os.path.join(self._work_path, self._bios_path))
        # Remove the tailing null characters
        ro_fwid = self._bios_handler.get_section_fwid('ro').rstrip('\0')
        rw_fwid = self._bios_handler.get_section_fwid('a').rstrip('\0')
        return (ro_fwid, rw_fwid)

    def retrieve_ecid(self):
        """Retrieve shellball's ecid.

        This method should be called after _setup_temp_dir.

        Returns:
            Shellball's ecid.
        """
        self._ec_handler.new_image(
                os.path.join(self._work_path, self._ec_path))
        fwid = self._ec_handler.get_section_fwid('rw')
        # Remove the tailing null characters
        return fwid.rstrip('\0')

    def retrieve_ec_hash(self):
        """Retrieve the hex string of the EC hash."""
        return self._ec_handler.get_section_hash('rw')

    def modify_ecid_and_flash_to_bios(self):
        """Modify ecid, put it to AP firmware, and flash it to the system.

        This method is used for testing EC software sync for EC EFS (Early
        Firmware Selection). It creates a slightly different EC RW image
        (a different EC fwid) in AP firmware, in order to trigger EC
        software sync on the next boot (a different hash with the original
        EC RW).

        The steps of this method:
         * Modify the EC fwid by appending a '~', like from
           'fizz_v1.1.7374-147f1bd64' to 'fizz_v1.1.7374-147f1bd64~'.
         * Resign the EC image.
         * Store the modififed EC RW image to CBFS component 'ecrw' of the
           AP firmware's FW_MAIN_A and FW_MAIN_B, and also the new hash.
         * Resign the AP image.
         * Flash the modified AP image back to the system.
        """
        self.cbfs_setup_work_dir()

        fwid = self.retrieve_ecid()
        if fwid.endswith('~'):
            raise FirmwareUpdaterError('The EC fwid is already modified')

        # Modify the EC FWID and resign
        fwid = fwid[:-1] + '~'
        self._ec_handler.set_section_fwid('rw', fwid)
        self._ec_handler.resign_ec_rwsig()

        # Replace ecrw to the new one
        ecrw_bin_path = os.path.join(self._cbfs_work_path,
                                     chip_utils.ecrw.cbfs_bin_name)
        self._ec_handler.dump_section_body('rw', ecrw_bin_path)

        # Replace ecrw.hash to the new one
        ecrw_hash_path = os.path.join(self._cbfs_work_path,
                                      chip_utils.ecrw.cbfs_hash_name)
        with open(ecrw_hash_path, 'w') as f:
            f.write(self.retrieve_ec_hash())

        # Store the modified ecrw and its hash to cbfs
        self.cbfs_replace_chip(chip_utils.ecrw.fw_name, extension='')

        # Resign and flash the AP firmware back to the system
        self.cbfs_sign_and_flash()

    def resign_firmware(self, version=None, work_path=None):
        """Resign firmware with version.

        Args:
            version: new firmware version number, default to no modification.
            work_path: work path, default to the updater work path.
        """
        if work_path is None:
            work_path = self._work_path
        self.os_if.run_shell_command(
                '/usr/share/vboot/bin/resign_firmwarefd.sh '
                '%s %s %s %s %s %s %s %s' % (
                    os.path.join(work_path, self._bios_path),
                    os.path.join(self._temp_path, 'output.bin'),
                    os.path.join(self._keys_path, 'firmware_data_key.vbprivk'),
                    os.path.join(self._keys_path, 'firmware.keyblock'),
                    os.path.join(self._keys_path,
                                 'dev_firmware_data_key.vbprivk'),
                    os.path.join(self._keys_path, 'dev_firmware.keyblock'),
                    os.path.join(self._keys_path, 'kernel_subkey.vbpubk'),
                    ('%d' % version) if version is not None else ''))
        self.os_if.copy_file('%s' % os.path.join(self._temp_path, 'output.bin'),
                             '%s' % os.path.join(
                                 work_path, self._bios_path))

    def _detect_image_paths(self):
        """Scans shellball to find correct bios and ec image paths."""
        def _extract_path_from_match(match_result, model):
          """Extract a path from a matched line of setvars.sh.

          Args:
            match_result: Match object: group 1 contains the quoted filename.
            model: Name of model to use to resolve ${MODEL_DIR} in the filename.

          Returns:
            pathname to firmware file (e.g. 'models/grunt/bios.bin').
          """
          pathname = match_result.group(1).replace('"', '')
          pathname = pathname.replace('${MODEL_DIR}', 'models/' + model)
          return pathname

        model_result = self.os_if.run_shell_command_get_output(
            'mosys platform model')
        if model_result:
            model = model_result[0]
            search_path = os.path.join(
                self._work_path, 'models', model, 'setvars.sh')
            grep_result = self.os_if.run_shell_command_get_output(
                'grep IMAGE_MAIN= %s' % search_path)
            if grep_result:
                match = re.match('IMAGE_MAIN=(.*)', grep_result[0])
                if match:
                  self._bios_path = _extract_path_from_match(match, model)
            grep_result = self.os_if.run_shell_command_get_output(
                'grep IMAGE_EC= %s' % search_path)
            if grep_result:
                match = re.match('IMAGE_EC=(.*)', grep_result[0])
                if match:
                  self._ec_path = _extract_path_from_match(match, model)

    def _update_target_fwid(self):
        """Update target fwid/ecid in the setvars.sh."""
        model_result = self.os_if.run_shell_command_get_output(
            'mosys platform model')
        if model_result:
            model = model_result[0]
            setvars_path = os.path.join(
                self._work_path, 'models', model, 'setvars.sh')
            if self.os_if.path_exists(setvars_path):
                ro_fwid, rw_fwid = self.retrieve_fwid()
                ecid = self.retrieve_ecid()
                args = ['-i']
                args.append(
                    '"s/TARGET_FWID=\\".*\\"/TARGET_FWID=\\"%s\\"/g"'
                    % rw_fwid)
                args.append(setvars_path)
                cmd = 'sed %s' % ' '.join(args)
                self.os_if.run_shell_command(cmd)

                args = ['-i']
                args.append(
                    '"s/TARGET_RO_FWID=\\".*\\"/TARGET_RO_FWID=\\"%s\\"/g"'
                    % ro_fwid)
                args.append(setvars_path)
                cmd = 'sed %s' % ' '.join(args)
                self.os_if.run_shell_command(cmd)

                args = ['-i']
                args.append(
                    '"s/TARGET_ECID=\\".*\\"/TARGET_ECID=\\"%s\\"/g"'
                    % ecid)
                args.append(setvars_path)
                cmd = 'sed %s' % ' '.join(args)
                self.os_if.run_shell_command(cmd)

    def extract_shellball(self, append=None):
        """Extract the working shellball.

        Args:
            append: decide which shellball to use with format
                chromeos-firmwareupdate-[append]. Use 'chromeos-firmwareupdate'
                if append is None.
        """
        working_shellball = os.path.join(self._temp_path,
                                         'chromeos-firmwareupdate')
        if append:
            working_shellball = working_shellball + '-%s' % append

        self.os_if.run_shell_command('sh %s --sb_extract %s' % (
                working_shellball, self._work_path))

        self._detect_image_paths()

    def repack_shellball(self, append=None):
        """Repack shellball with new fwid.

        New fwid follows the rule: [orignal_fwid]-[append].

        Args:
            append: save the new shellball with a suffix, for example,
                chromeos-firmwareupdate-[append]. Use 'chromeos-firmwareupdate'
                if append is None.
        """
        self._update_target_fwid();

        working_shellball = os.path.join(self._temp_path,
                                         'chromeos-firmwareupdate')
        if append:
            self.os_if.copy_file(working_shellball,
                                 working_shellball + '-%s' % append)
            working_shellball = working_shellball + '-%s' % append

        self.os_if.run_shell_command('sh %s --sb_repack %s' % (
                working_shellball, self._work_path))

        if append:
            args = ['-i']
            args.append(
                    '"s/TARGET_FWID=\\"\\(.*\\)\\"/TARGET_FWID=\\"\\1.%s\\"/g"'
                    % append)
            args.append(working_shellball)
            cmd = 'sed %s' % ' '.join(args)
            self.os_if.run_shell_command(cmd)

            args = ['-i']
            args.append('"s/TARGET_UNSTABLE=\\".*\\"/TARGET_UNSTABLE=\\"\\"/g"')
            args.append(working_shellball)
            cmd = 'sed %s' % ' '.join(args)
            self.os_if.run_shell_command(cmd)

    def run_firmwareupdate(self, mode, updater_append=None, options=[]):
        """Do firmwareupdate with updater in temp_dir.

        Args:
            updater_append: decide which shellball to use with format
                chromeos-firmwareupdate-[append]. Use'chromeos-firmwareupdate'
                if updater_append is None.
            mode: ex.'autoupdate', 'recovery', 'bootok', 'factory_install'...
            options: ex. ['--noupdate_ec', '--nocheck_rw_compatible'] or [] for
                no option.
        """
        if updater_append:
            updater = os.path.join(
                self._temp_path, 'chromeos-firmwareupdate-%s' % updater_append)
        else:
            updater = os.path.join(self._temp_path, 'chromeos-firmwareupdate')
        command = '/bin/sh %s --mode %s %s' % (updater, mode, ' '.join(options))

        if mode == 'bootok':
            # Since CL:459837, bootok is moved to chromeos-setgoodfirmware.
            new_command = '/usr/sbin/chromeos-setgoodfirmware'
            command = 'if [ -e %s ]; then %s; else %s; fi' % (
                    new_command, new_command, command)

        self.os_if.run_shell_command(command)

    def cbfs_setup_work_dir(self):
        """Sets up cbfs on DUT.

        Finds bios.bin on the DUT and sets up a temp dir to operate on
        bios.bin.  If a bios.bin was specified, it is copied to the DUT
        and used instead of the native bios.bin.

        Returns:
            The cbfs work directory path.
        """

        self.os_if.remove_dir(self._cbfs_work_path)
        self.os_if.copy_dir(self._work_path, self._cbfs_work_path)

        return self._cbfs_work_path

    def cbfs_extract_chip(self, fw_name, extension='.bin'):
        """Extracts chip firmware blob from cbfs.

        For a given chip type, looks for the corresponding firmware
        blob and hash in the specified bios.  The firmware blob and
        hash are extracted into self._cbfs_work_path.

        The extracted blobs will be <fw_name><extension> and
        <fw_name>.hash located in cbfs_work_path.

        Args:
            fw_name: Chip firmware name to be extracted.
            extension: Extension of the name of the cbfs component.

        Returns:
            Boolean success status.
        """

        bios = os.path.join(self._cbfs_work_path, self._bios_path)
        fw = fw_name
        cbfs_extract = '%s %s extract -r FW_MAIN_A -n %s%%s -f %s%%s' % (
            self.CBFSTOOL,
            bios,
            fw,
            os.path.join(self._cbfs_work_path, fw))

        cmd = cbfs_extract % (extension, extension)
        if self.os_if.run_shell_command_get_status(cmd) != 0:
            return False

        cmd = cbfs_extract % ('.hash', '.hash')
        if self.os_if.run_shell_command_get_status(cmd) != 0:
            return False

        return True

    def cbfs_get_chip_hash(self, fw_name):
        """Returns chip firmware hash blob.

        For a given chip type, returns the chip firmware hash blob.
        Before making this request, the chip blobs must have been
        extracted from cbfs using cbfs_extract_chip().
        The hash data is returned as hexadecimal string.

        Args:
            fw_name:
                Chip firmware name whose hash blob to get.

        Returns:
            Boolean success status.

        Raises:
            shell_wrapper.ShellError: Underlying remote shell
                operations failed.
        """

        hexdump_cmd = '%s %s.hash' % (
            self.HEXDUMP,
            os.path.join(self._cbfs_work_path, fw_name))
        hashblob = self.os_if.run_shell_command_get_output(hexdump_cmd)
        return hashblob

    def cbfs_replace_chip(self, fw_name, extension='.bin'):
        """Replaces chip firmware in CBFS (bios.bin).

        For a given chip type, replaces its firmware blob and hash in
        bios.bin.  All files referenced are expected to be in the
        directory set up using cbfs_setup_work_dir().

        Args:
            fw_name: Chip firmware name to be replaced.
            extension: Extension of the name of the cbfs component.

        Returns:
            Boolean success status.

        Raises:
            shell_wrapper.ShellError: Underlying remote shell
                operations failed.
        """

        bios = os.path.join(self._cbfs_work_path, self._bios_path)
        rm_hash_cmd = '%s %s remove -r FW_MAIN_A,FW_MAIN_B -n %s.hash' % (
            self.CBFSTOOL, bios, fw_name)
        rm_bin_cmd = '%s %s remove -r FW_MAIN_A,FW_MAIN_B -n %s%s' % (
            self.CBFSTOOL, bios, fw_name, extension)
        expand_cmd = '%s %s expand -r FW_MAIN_A,FW_MAIN_B' % (
            self.CBFSTOOL, bios)
        add_hash_cmd = ('%s %s add -r FW_MAIN_A,FW_MAIN_B -t raw -c none '
                        '-f %s.hash -n %s.hash') % (
                            self.CBFSTOOL,
                            bios,
                            os.path.join(self._cbfs_work_path, fw_name),
                            fw_name)
        add_bin_cmd = ('%s %s add -r FW_MAIN_A,FW_MAIN_B -t raw -c lzma '
                       '-f %s%s -n %s%s') % (
                           self.CBFSTOOL,
                           bios,
                           os.path.join(self._cbfs_work_path, fw_name),
                           extension,
                           fw_name,
                           extension)
        truncate_cmd = '%s %s truncate -r FW_MAIN_A,FW_MAIN_B' % (
            self.CBFSTOOL, bios)

        self.os_if.run_shell_command(rm_hash_cmd)
        self.os_if.run_shell_command(rm_bin_cmd)
        try:
            self.os_if.run_shell_command(expand_cmd)
        except shell_wrapper.ShellError:
            self.os_if.log(('%s may be too old, '
                            'continuing without "expand" support') %
                           self.CBFSTOOL)

        self.os_if.run_shell_command(add_hash_cmd)
        self.os_if.run_shell_command(add_bin_cmd)
        try:
            self.os_if.run_shell_command(truncate_cmd)
        except shell_wrapper.ShellError:
            self.os_if.log(('%s may be too old, '
                            'continuing without "truncate" support') %
                           self.CBFSTOOL)

        return True

    def cbfs_sign_and_flash(self):
        """Signs CBFS (bios.bin) and flashes it."""
        self.resign_firmware(work_path=self._cbfs_work_path)
        self._bios_handler.new_image(
                os.path.join(self._cbfs_work_path, self._bios_path))
        self._bios_handler.write_whole()
        return True

    def get_temp_path(self):
        """Get temp directory path."""
        return self._temp_path

    def get_keys_path(self):
        """Get keys directory path."""
        return self._keys_path

    def get_cbfs_work_path(self):
        """Get cbfs work directory path."""
        return self._cbfs_work_path

    def get_work_path(self):
        """Get work directory path."""
        return self._work_path

    def get_bios_relative_path(self):
        """Gets the relative path of the bios image in the shellball."""
        return self._bios_path

    def get_ec_relative_path(self):
        """Gets the relative path of the ec image in the shellball."""
        return self._ec_path
