# Copyright (c) 2012 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.

from threading import Timer
import logging
import re
import time

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


def delayed(seconds): # pylint:disable=missing-docstring
    def decorator(f): # pylint:disable=missing-docstring
        def wrapper(*args, **kargs): # pylint:disable=missing-docstring
            t = Timer(seconds, f, args, kargs)
            t.start()
        return wrapper
    return decorator


class firmware_ECLidSwitch(FirmwareTest):
    """
    Servo based EC lid switch test.
    """
    version = 1

    # Delay between closing and opening the lid
    LID_DELAY = 1

    # Delay to allow FAFT client receive command
    RPC_DELAY = 2

    # Delay between shutdown and wakeup by lid switch
    WAKE_DELAY = 10

    def initialize(self, host, cmdline_args):
        super(firmware_ECLidSwitch, self).initialize(host, cmdline_args)
        # Only run in normal mode
        self.switcher.setup_mode('normal')

    def _open_lid(self):
        """Open lid by servo."""
        self.servo.set('lid_open', 'yes')

    def _close_lid(self):
        """Close lid by servo."""
        self.servo.set('lid_open', 'no')

    @delayed(RPC_DELAY)
    def delayed_open_lid(self):
        """Delay by RPC_DELAY and then open lid by servo."""
        self._open_lid()

    @delayed(RPC_DELAY)
    def delayed_close_lid(self):
        """Delay by RPC_DELAY and then close lid by servo."""
        self._close_lid()

    def _wake_by_lid_switch(self):
        """Wake DUT with lid switch."""
        self._close_lid()
        time.sleep(self.LID_DELAY)
        self._open_lid()

    def delayed_wake(self):
        """
        Confirm the device is in G3, wait for WAKE_DELAY, and then wake DUT
        with lid switch.
        """
        self.check_shutdown_power_state(self.POWER_STATE_G3, pwr_retries=10)
        time.sleep(self.WAKE_DELAY)
        self._wake_by_lid_switch()

    def immediate_wake(self):
        """Confirm the device is in G3 and then wake DUT with lid switch."""
        self.check_shutdown_power_state(self.POWER_STATE_G3, pwr_retries=10)
        self._wake_by_lid_switch()

    def shutdown_and_wake(self, shutdown_func, wake_func):
        """Software shutdown and wake.

        Args:
          shutdown_func: Function to shut down DUT.
          wake_func: Delayed function to wake DUT.
        """
        shutdown_func()
        wake_func()

    def _get_keyboard_backlight(self):
        """Get keyboard backlight brightness.

        Returns:
          Backlight brightness percentage 0~100. If it is disabled, 0 is
            returned.
        """
        cmd = 'ectool pwmgetkblight'
        pattern_percent = re.compile(
            'Current keyboard backlight percent: (\d*)')
        pattern_disable = re.compile('Keyboard backlight disabled.')
        lines = self.faft_client.system.run_shell_command_get_output(cmd)
        for line in lines:
            matched_percent = pattern_percent.match(line)
            if matched_percent is not None:
                return int(matched_percent.group(1))
            matched_disable = pattern_disable.match(line)
            if matched_disable is not None:
                return 0
        raise error.TestError('Cannot get keyboard backlight status.')

    def _set_keyboard_backlight(self, value):
        """Set keyboard backlight brightness.

        Args:
          value: Backlight brightness percentage 0~100.
        """
        cmd = 'ectool pwmsetkblight %d' % value
        self.faft_client.system.run_shell_command(cmd)

    def check_keycode(self):
        """Check that lid open/close do not send power button keycode.

        Returns:
          True if no power button keycode is captured. Otherwise, False.
        """
        # Don't check the keycode if we don't have a keyboard.
        if not self.check_ec_capability(['keyboard'], suppress_warning=True):
            return True

        self._open_lid()
        self.delayed_close_lid()
        if self.faft_client.system.check_keys([]) < 0:
            return False
        self.delayed_open_lid()
        if self.faft_client.system.check_keys([]) < 0:
            return False
        return True

    def check_backlight(self):
        """Check if lid open/close controls keyboard backlight as expected.

        Returns:
          True if keyboard backlight is turned off when lid close and on when
           lid open.
        """
        if not self.check_ec_capability(['kblight'], suppress_warning=True):
            return True
        ok = True
        original_value = self._get_keyboard_backlight()
        self._set_keyboard_backlight(100)

        self._close_lid()
        if self._get_keyboard_backlight() != 0:
            logging.error("Keyboard backlight still on when lid close.")
            ok = False
        self._open_lid()
        if self._get_keyboard_backlight() == 0:
            logging.error("Keyboard backlight still off when lid open.")
            ok = False

        self._set_keyboard_backlight(original_value)
        return ok

    def check_keycode_and_backlight(self):
        """
        Disable powerd to prevent DUT shutting down during test. Then check
        if lid switch event controls keycode and backlight as we expected.
        """
        ok = True
        logging.info("Stopping powerd")
        self.faft_client.system.run_shell_command('stop powerd')
        if not self.check_keycode():
            logging.error("check_keycode failed.")
            ok = False
        if not self.check_backlight():
            logging.error("check_backlight failed.")
            ok = False
        logging.info("Restarting powerd")
        self.faft_client.system.run_shell_command('start powerd')
        return ok

    def run_once(self):
        """Runs a single iteration of the test."""
        if not self.check_ec_capability(['lid']):
            raise error.TestNAError("Nothing needs to be tested on this device")

        logging.info("Shut down and then wake up DUT after a delay.")
        self.switcher.mode_aware_reboot(
                'custom',
                lambda:self.shutdown_and_wake(
                        shutdown_func=self.run_shutdown_cmd,
                        wake_func=self.delayed_wake))
        logging.info("Shut down and then wake up DUT immediately.")
        self.switcher.mode_aware_reboot(
                'custom',
                lambda:self.shutdown_and_wake(
                        shutdown_func=self.run_shutdown_cmd,
                        wake_func=self.immediate_wake))
        logging.info("Close and then open the lid when not logged in.")
        self.switcher.mode_aware_reboot(
                'custom',
                lambda:self.shutdown_and_wake(
                        shutdown_func=self._close_lid,
                        wake_func=self.immediate_wake))
        logging.info("Check keycode and backlight.")
        self.check_state(self.check_keycode_and_backlight)
