# Copyright (c) 2019 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 random
import time

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

# Serial number cannot contain vowels after the first character, so don't allow
# any vowels in this test.
VALID_CHARS = "BCDFGHJKLMNPQRSTVWXYZ0123456789"

class firmware_SetSerialNumber(FirmwareTest):
    """
    Servo based test to set serial number in firmware.

    Test that setting the serial number in firmware during an onsite RMA works.
    Mainboards for onsite RMA will have WP# asserted, flash WP bit cleared,
    the serial_number in VPD set to all spaces, and be in dev mode. After the
    serial number is set in firmware flash write protect will be enabled and
    the device will be in normal mode.
    """
    version = 1

    def start_serial_number_prompt(self):
        """Repeatedly press ctrl-s to bring up serial number prompt."""
        logging.info("Pressing Ctrl-S.")
        timeout = time.time() + (self.faft_config.firmware_screen)
        while time.time() < timeout:
            self.servo.set_nocheck('ctrl_s', 'tab')
            time.sleep(1)

    def generate_serial_number_string(self):
        """Generate a valid serial number based on config"""
        return ''.join(random.choice(VALID_CHARS)
                       for _ in range(self.faft_config.serial_number_length))

    def send_string(self, keys):
        """Send a string over a servo"""
        for key in keys.lower():
            self.servo.set_nocheck('arb_key_config', key)
            self.servo.set_nocheck('arb_key', 'tab')

    def initialize(self, host, cmdline_args):
        super(firmware_SetSerialNumber, self).initialize(host, cmdline_args)

        if self.faft_config.serial_number_length == 0:
            raise error.TestNAError("This test is only valid on devices where "
                                    "serial number can be set in firmware.")

        # This test is run on developer mode only.
        self.switcher.setup_mode('dev')

        # Disable fw wp to clear VPD value
        self.set_hardware_write_protect(False)

        self.faft_client.system.run_shell_command_get_output(
            'flashrom -p host --wp-disable')

        self.faft_client.system.run_shell_command_get_output(
            'vpd -i RO_VPD -s serial_number="%s"' %
            (' ' * self.faft_config.serial_number_length)
        )

        self.set_hardware_write_protect(True)

    def run_once(self):
        """Run the test"""
        serial_number = self.generate_serial_number_string()
        logging.info("Setting serial number to '%s'.", serial_number)

        self.switcher.simple_reboot()
        if not self.faft_config.rma_entered_automatically:
            self.start_serial_number_prompt()
        else:
            time.sleep(self.faft_config.firmware_screen)
        self.send_string(serial_number)
        # Press enter on set
        self.servo.enter_key()
        # Press enter on confirm
        self.servo.enter_key()
        self.switcher.wait_for_client()

        # Check that device is no longer in dev mode
        self.checkers.mode_checker('normal')

        # Check that serial_number is correctly set
        result = self.faft_client.system.run_shell_command_get_output(
            'vpd -i RO_VPD -g serial_number')[0]

        if result != serial_number:
            raise error.TestFail("Expected serial number '%s' but got '%s'" % (
                serial_number, result))

        # Check that write protect is correctly set
        result = self.faft_client.system.run_shell_command_get_output(
            'flashrom -p host --wp-status')

        result = '\n'.join(result)

        if ('is disabled' in result or
                'start=0x00000000' in result or
                'len=0x00000000' in result):
           raise error.TestFail('Expected write protection to be enabled '
                                'but output was:\n\n%s' % result)

    def cleanup(self):
        self.servo.set_nocheck('fw_wp_state', 'reset')
        super(firmware_SetSerialNumber, self).cleanup()
