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

import logging
import time
from threading import Timer

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


class firmware_BaseECKeyboard(FirmwareTest):
    """Servo-based BaseEC keyboard test.

    The base should be connected to the servo v4 board through an extra
    micro-servo. It talks to the base EC to emulate key-press.
    """
    version = 1

    # Delay to ensure client is ready to read the key press.
    KEY_PRESS_DELAY = 2

    # Delay to wait until the UI starts.
    START_UI_DELAY = 1

    # Delay to wait until developer console is open.
    DEV_CONSOLE_DELAY = 2


    def initialize(self, host, cmdline_args):
        super(firmware_BaseECKeyboard, self).initialize(host, cmdline_args)
        # Don't require USB disk
        self.setup_usbkey(usbkey=False)
        # Only run in normal mode
        self.switcher.setup_mode('normal')


    def cleanup(self):
        # Restart UI anyway, in case the test failed in the middle
        try:
            self.faft_client.System.RunShellCommand('start ui | true')
        except Exception as e:
            logging.error("Caught exception: %s", str(e))
        super(firmware_BaseECKeyboard, self).cleanup()


    def _base_keyboard_checker(self, press_action):
        """Press key and check from DUT.

        Args:
          press_action: A callable that would press the keys when called.

        Returns:
          True if passed; or False if failed.
        """
        # Stop UI so that key presses don't go to Chrome.
        self.faft_client.System.RunShellCommand('stop ui')

        # Start a thread to perform the key-press action
        Timer(self.KEY_PRESS_DELAY, press_action).start()

        # Invoke client side script to monitor keystrokes.
        # The codes are linux input event codes.
        # The order doesn't matter.
        result = self.faft_client.System.CheckKeys([
                linux_input.KEY_ENTER,
                linux_input.KEY_LEFTCTRL,
                linux_input.KEY_D])

        # Turn UI back on
        self.faft_client.System.RunShellCommand('start ui')
        time.sleep(self.START_UI_DELAY)

        return result


    def keyboard_checker(self):
        """Press 'd', Ctrl, ENTER by servo and check from DUT."""

        def keypress(): # pylint:disable=missing-docstring
            self.servo.enter_key()
            self.servo.ctrl_d()

        return self._base_keyboard_checker(keypress)


    def switch_tty2(self):
        """Switch to tty2 console."""
        self.base_ec.key_down('<ctrl_l>')
        self.base_ec.key_down('<alt_l>')
        self.base_ec.key_down('<f2>')
        self.base_ec.key_up('<f2>')
        self.base_ec.key_up('<alt_l>')
        self.base_ec.key_up('<ctrl_l>')
        time.sleep(self.DEV_CONSOLE_DELAY)


    def reboot_by_keyboard(self):
        """Reboot DUT by keyboard.

        Simulate key press sequence to log into console and then issue reboot
        command.
        """
        # Assume that DUT runs a test image, which has tty2 console and root
        # access.
        self.switch_tty2()
        self.base_ec.send_key_string('root<enter>')
        self.base_ec.send_key_string('test0000<enter>')
        self.base_ec.send_key_string('reboot<enter>')


    def run_once(self):
        """Runs a single iteration of the test."""
        if not self.base_ec:
            raise error.TestError('The base not found on servo. Wrong setup?')

        logging.info('Testing keypress by servo...')
        self.check_state(self.keyboard_checker)

        logging.info('Use key press simulation to issue reboot command...')
        self.switcher.mode_aware_reboot('custom', self.reboot_by_keyboard)
