# Copyright 2022 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import logging
import time

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


class firmware_GSCSetAPROV1(Cr50Test):
    """
    Verify a dut can set the AP RO hash when board id type is erased.
    """
    version = 1

    TEST_AP_RO_VER = 1

    # gsctool errors.
    ERR_UNPROGRAMMED = 'AP RO hash unprogrammed'
    ERR_BID_PROGRAMMED = 'BID already programmed'

    # ap_ro_hash.py errors.
    AP_RO_ERR_ALREADY_PROGRAMMED = 'Already programmed'
    AP_RO_ERR_BID_PROGRAMMED = 'BID programmed'

    def initialize(self, host, cmdline_args, full_args={}):
        """Initialize servo"""
        super(firmware_GSCSetAPROV1,
              self).initialize(host,
                               cmdline_args,
                               full_args,
                               restore_cr50_image=True,
                               restore_cr50_board_id=True)

        if not self.gsc.ap_ro_version_is_supported(self.TEST_AP_RO_VER):
            raise error.TestNAError('GSC does not support AP RO v%s' %
                                    self.TEST_AP_RO_VER)

    def get_hash(self):
        """Get the hash."""
        time.sleep(10)
        result = cr50_utils.GSCTool(self.host, ['-a', '-A'])
        saved_hash = result.stdout.split(':')[-1].strip()
        logging.info('hash: %s', saved_hash)
        return None if self.ERR_UNPROGRAMMED in saved_hash else saved_hash

    def clear_hash(self, expect_error=False):
        """Clear the Hash."""
        result = cr50_utils.GSCTool(self.host, ['-a', '-H'],
                                    ignore_status=expect_error)
        if expect_error and (result.exit_status != 3
                             or self.ERR_BID_PROGRAMMED not in result.stderr):
            raise error.TestFail('Unexpected error clearing hash %r',
                                 result.stderr)
        self.get_hash()

    def set_hash(self, expected_error=None):
        """Set the Hash."""
        result = self.host.run('ap_ro_hash.py -v True GBB',
                               ignore_status=not not expected_error)
        if expected_error:
            if expected_error not in result.stderr:
                raise error.TestFail('Did not find %r in error' %
                                     expected_error)
        elif result.exit_status:
            raise error.TestFail('Error saving hash')
        return self.get_hash()

    def run_once(self):
        """Verify the AP RO hash can be updated when the BID type isn't set"""
        brand = self.get_device_brand()
        if not brand:
            raise error.TestNAError('Cannot run without brand')

        # Erase the board id if its set.
        if not self.gsc.get_board_id()[1]:
            logging.info('Erasing BID')
            self.eraseflashinfo_and_restore_image()
        bid = self.get_saved_cr50_original_version()[2]
        flags = int(bid.split(':')[-1] if bid else '0', 16)

        self.clear_hash()
        self.set_hash()
        self.set_hash(expected_error=self.AP_RO_ERR_ALREADY_PROGRAMMED)

        cr50_utils.SetChipBoardId(self.host, '0xffffffff', flags)

        self.clear_hash()
        self.set_hash()
        self.set_hash(expected_error=self.AP_RO_ERR_ALREADY_PROGRAMMED)
        self.clear_hash()

        cr50_utils.SetChipBoardId(self.host, brand, flags)

        self.clear_hash(expect_error=True)
        self.set_hash(expected_error=self.AP_RO_ERR_BID_PROGRAMMED)
