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

"""This is a FAFT test to check if TCPCs are up-to-date.

This test figures out which TCPCs exist on a DUT and matches
these up with corresponding firmware blobs in the system
image shellball.  If mismatches are detected, the test fails.

The test can optionally be invoked with --args bios=... to
specify an alternate reference firmware image.
"""

import logging
import os

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


class firmware_CompareChipFwToShellBall(FirmwareTest):

    """Compares the active DUT chip firmware with reference.

    FAFT test to verify that a DUT runs the expected chip
    firmware based on the system shellball or a specified
    reference image.
    """
    version = 1

    BIOS = 'bios.bin'
    MAXPORTS = 100

    def initialize(self, host, cmdline_args):
        super(firmware_CompareChipFwToShellBall,
              self).initialize(host, cmdline_args)
        dict_args = utils.args_to_dict(cmdline_args)
        self.new_bios_path = dict_args['bios'] if 'bios' in dict_args else None
        self.cbfs_work_dir = None
        self.dut_bios_path = None

    def cleanup(self):
        try:
            if self.cbfs_work_dir:
                self.faft_client.System.RemoveDir(self.cbfs_work_dir)
        except Exception as e:
            logging.error("Caught exception: %s", str(e))
        super(firmware_CompareChipFwToShellBall, self).cleanup()

    def dut_get_chip(self, port):
        """Gets the chip info for a port.

        Args:
            port: TCPC port number on DUT

        Returns:
            A chip object if available, else None.
        """

        cmd = 'mosys -s product_id pd chip %d' % port
        chip_id = self.faft_client.System.RunShellCommandGetOutput(cmd)
        if not chip_id:
            # chip probably does not exist
            return None
        chip_id = chip_id[0]

        if chip_id not in chip_utils.chip_id_map:
            logging.info('chip type %s not recognized', chip_id)
            return chip_utils.generic_chip()
        chip = chip_utils.chip_id_map[chip_id]()

        cmd = 'mosys -s fw_version pd chip %d' % port
        fw_rev = self.faft_client.System.RunShellCommandGetOutput(cmd)
        if not fw_rev:
            # chip probably does not exist
            return None
        fw_rev = fw_rev[0]
        chip.set_fw_ver_from_string(fw_rev)
        return chip

    def dut_scan_chips(self):
        """Scans for TCPC chips on DUT.

        Returns:
            A tuple (S, L) consisting of a set S of chip types and a list L
            of chips indexed by port number found on on the DUT.

        Raises:
            TestFail: DUT has >= MAXPORTS pd ports.
        """

        chip_types = set()
        port2chip = []
        for port in xrange(self.MAXPORTS):
            chip = self.dut_get_chip(port)
            if not chip:
                return (chip_types, port2chip)
            port2chip.append(chip)
            chip_types.add(type(chip))
        logging.error('found at least %u TCPC ports '
                      '- please update test to handle more ports '
                      'if this is expected.', self.MAXPORTS)
        raise error.TestFail('MAXPORTS exceeded' % self.MAXPORTS)

    def dut_locate_bios_bin(self):
        """Finds bios.bin on DUT.

        Figures out where FAFT unpacked the shellball
        and return path to extracted bios.bin.

        Returns:
            Full path of bios.bin on DUT.
        """

        work_path = self.faft_client.Updater.GetWorkPath()
        bios_relative_path = self.faft_client.Updater.GetBiosRelativePath()
        bios_bin = os.path.join(work_path, bios_relative_path)
        return bios_bin

    def dut_prep_cbfs(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.
        """

        cbfs_path = self.faft_client.Updater.CbfsSetupWorkDir()
        bios_relative_path = self.faft_client.Updater.GetBiosRelativePath()
        self.cbfs_work_dir = cbfs_path
        self.dut_bios_path = os.path.join(cbfs_path, bios_relative_path)

    def dut_cbfs_extract_chips(self, chip_types):
        """Extracts firmware hash blobs from cbfs.

        Iterates over requested chip types and looks for corresponding
        firmware hash blobs in cbfs.  These firmware hash blobs are
        extracted into cbfs_work_dir.

        Args:
            chip_types:
                A set of chip types for which the hash blobs will be
                extracted.

        Returns:
            A dict mapping found chip names to chip instances.
        """

        cbfs_chip_info = {}
        for chip_type in chip_types:
            chip = chip_type()
            fw = chip.fw_name
            if not fw:
                # must be an unfamiliar chip
                continue

            if not self.faft_client.Updater.CbfsExtractChip(chip.fw_name):
                logging.warning('%s firmware not bundled in %s',
                                chip.chip_name, self.BIOS)
                continue

            hashblob = self.faft_client.Updater.CbfsGetChipHash(
                chip.fw_name)
            if not hashblob:
                logging.warning('%s firmware hash not extracted from %s',
                                chip.chip_name, self.BIOS)
                continue

            bundled_fw_ver = chip.fw_ver_from_hash(hashblob)
            if not bundled_fw_ver:
                raise error.TestFail(
                    'could not decode %s firmware hash: %s' % (
                        chip.chip_name, hashblob))

            chip.set_fw_ver_from_string(bundled_fw_ver)
            cbfs_chip_info[chip.chip_name] = chip
            logging.info('%s bundled firmware for %s is version %s',
                         self.BIOS, chip.chip_name, bundled_fw_ver)
        return cbfs_chip_info

    def check_chip_versions(self, port2chip, ref_chip_info):
        """Verifies DUT chips have expected firmware.

        Iterates over found DUT chips and verifies their firmware version
        matches the chips found in the reference ref_chip_info map.

        Args:
            port2chip: A list of chips to verify against ref_chip_info.
            ref_chip_info: A dict of reference chip chip instances indexed
                by chip name.
        """

        for p, pinfo in enumerate(port2chip):
            if not pinfo.fw_ver:
                # must be an unknown chip
                continue
            msg = 'DUT port %s is a %s running firmware 0x%02x' % (
                p, pinfo.chip_name, pinfo.fw_ver)
            if pinfo.chip_name not in ref_chip_info:
                logging.warning('%s but there is no reference version', msg)
                continue
            expected_fw_ver = ref_chip_info[pinfo.chip_name].fw_ver
            logging.info('%s%s', msg,
                         ('' if pinfo.fw_ver == expected_fw_ver else
                          ' (expected 0x%02x)' % expected_fw_ver))

            if pinfo.fw_ver != expected_fw_ver:
                msg = '%s firmware was not updated to 0x%02x' % (
                    pinfo.chip_name, expected_fw_ver)
                raise error.TestFail(msg)

    def run_once(self, host):
        """Runs a single iteration of the test."""
        # Make sure the client library is on the device so that the proxy
        # code is there when we try to call it.

        (dut_chip_types, dut_chips) = self.dut_scan_chips()
        if not dut_chip_types:
            logging.info('mosys reported no chips on DUT, skipping test')
            return

        self.dut_prep_cbfs()
        if self.new_bios_path:
            host.send_file(self.new_bios_path, self.dut_bios_path)

        ref_chip_info = self.dut_cbfs_extract_chips(dut_chip_types)
        self.check_chip_versions(dut_chips, ref_chip_info)
