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

import logging
import re
import time

from autotest_lib.client.common_lib import error, utils
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 firmware_Cr50GetName(Cr50Test):
    """Verify cr50-get-name.sh

    Verify cr50-get-name sets the correct board id and flags based on the
    given stage.
    """
    version = 1

    GET_NAME_SCRIPT = '/usr/share/cros/cr50-get-name.sh'
    # This translates to 'TEST'
    TEST_BRAND = 0x54455354
    MAX_VAL = 0xffffffff


    def initialize(self, host, cmdline_args, full_args={}):
        # Restore the original image, rlz code, and board id during cleanup.
        super(firmware_Cr50GetName, self).initialize(host, cmdline_args,
            full_args, restore_cr50_image=True, restore_cr50_board_id=True)

        if not self.host.path_exists(self.GET_NAME_SCRIPT):
            raise error.TestNAError('Device does not have "cr50-get-name"')

        efi_path = self.get_saved_eraseflashinfo_image_path()

        filesystem_util.make_rootfs_writable(self.host)
        cr50_utils.InstallImage(self.host, efi_path, cr50_utils.CR50_PROD)
        cr50_utils.InstallImage(self.host, efi_path, cr50_utils.CR50_PREPVT)

        # Update to the eraseflashinfo image so we can erase the board id after
        # we set it. This test is verifying cr50-get-name, so it is ok if cr50
        # is running a non-prod image.
        self.cr50_update(self.get_saved_dbg_image_path())
        self.cr50_update(efi_path, rollback=True)

        # Stop trunksd so it wont interfere with the update
        cr50_utils.StopTrunksd(self.host)

        # Get the current cr50 update messages. The test will keep track of the
        # last message and separate the current output from actual test results.
        self.get_result()


    def cleanup(self):
        """Reset the DUT to restore trunksd."""
        try:
            self.servo.get_power_state_controller().reset()
        finally:
            super(firmware_Cr50GetName, self).cleanup()


    def get_result(self):
        """Return the new cr50 update messages from /var/log/messages"""
        # Get the cr50 messages
        result = self.host.run('grep cr50 /var/log/messages').stdout.strip()

        if hasattr(self, '_last_message'):
            result = result.rsplit(self._last_message, 1)[-1]

        # Save the last line. It will be used to separate the current results
        # from later runs.
        self._last_message = result.rsplit('\n', 1)[-1]
        logging.debug('last cr50 update message: "%s"', self._last_message)
        return result


    def get_expected_result_re(self, brand, flags, erased):
        """Return the expected update message re given the test flags

        Args:
            brand: The board id value to test.
            flags: The flag value to test.
            erased: True if the board id is erased

        Returns:
            A string with info that must be found in /var/log/messages for valid
            update results.
        """
        expected_result = []

        if erased:
            board_id = 'ffffffff:ffffffff:ffffffff'
            # If the board id is erased, the device should update to the prod
            # image.
            ext = 'prod'
            expected_result.append('board ID is erased using prod image')
        else:
            board_id = '%08x:%08x:%08x' % (brand, brand ^ self.MAX_VAL, flags)
            ext = 'prepvt' if flags & 0x10 else 'prod'

        flag_str = board_id.rsplit(':', 1)[-1]

        expected_result.append("board_id: '%s' board_flags: '0x%s', extension: "
                "'%s'" % (board_id, flag_str, ext))
        expected_result.append('hashing /opt/google/cr50/firmware/cr50.bin.%s' %
                ext)
        return '(%s)' % '\n.*'.join(expected_result)


    def check_result(self, brand, flags, erased):
        """Verify the expected result string is found in the update messages

        Args:
            brand: The board id value to test.
            flags: The flag value to test.
            erased: True if the board id is erased

        Raises:
            TestFail if the expected result message did not match the update
            output
        """
        expected_result_re = self.get_expected_result_re(brand, flags, erased)
        result = self.get_result()
        match = re.search(expected_result_re, result)

        logging.debug('EXPECT: %s', expected_result_re)
        logging.debug('GOT: %s', result)

        if not match:
            raise error.TestFail('Unexpected result during update with %s' %
                    ('erased board id' if erased else '%x:%x' % (brand, flags)))

        logging.info('FOUND UPDATE RESULT:\n%s', match.groups()[0])


    def cr50_update_is_running(self):
        """Returns True if cr50-update is running on the host"""
        time.sleep(1)
        status = self.host.run('status cr50-update').stdout
        logging.info('cr50-update status: %s', status)
        return 'running' in status


    def run_update(self, brand, flags, clear_bid=False):
        """Set the board id then run cr50-update

        Args:
            brand: The board id int to test.
            flags: The flag int to test.
            clear_bid: True if the board id should be erased and not reset.
        """
        if not self.cr50.eraseflashinfo():
            raise error.TestError('Unable to erase the board id')

        if not clear_bid:
            cr50_utils.SetChipBoardId(self.host, brand, flags)

        # Get the current cr50 update messages. The test will keep track of the
        # last message and separate the current output from actual test results.
        self.get_result()
        # Run the update script script
        self.host.run('start cr50-update')
        utils.wait_for_value(self.cr50_update_is_running, expected_value=False,
                             timeout_sec=30)

        # Make sure cr50 used the right image.
        self.check_result(brand, flags, clear_bid)


    def run_once(self):
        """Verify cr50-get-name.sh"""
        # Test the MP flags
        self.run_update(self.TEST_BRAND, 0x7f00)

        # Test the pre-PVT flags
        self.run_update(self.TEST_BRAND, 0x7f10)

        # Erase the board id
        self.run_update(0, 0, clear_bid=True)

        # Make sure the script can tell the difference between an erased board
        # id and one set to 0xffffffff:0xffffffff.
        self.run_update(self.MAX_VAL, self.MAX_VAL)
