# 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):
    def decorator(f):
        def wrapper(*args, **kargs):
            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 wake by lid switch including kernel
    # shutdown time
    LONG_WAKE_DELAY = 25
    SHORT_WAKE_DELAY = 15

    def initialize(self, host, cmdline_args):
        super(firmware_ECLidSwitch, self).initialize(host, cmdline_args)
        # Only run in normal mode
        self.setup_dev_mode(False)

    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()

    @delayed(LONG_WAKE_DELAY)
    def long_delayed_wake(self):
        """Delay for LONG_WAKE_DELAY and then wake DUT with lid switch."""
        self._wake_by_lid_switch()

    @delayed(SHORT_WAKE_DELAY)
    def short_delayed_wake(self):
        """Delay for SHORT_WAKE_DELAY and then wake DUT with lid switch."""
        self._wake_by_lid_switch()

    def shutdown_and_wake(self, wake_func):
        """Software shutdown and delay. Then wake by lid switch.

        Args:
          wake_func: Delayed function to wake DUT.
        """
        self.faft_client.system.run_shell_command('shutdown -P now')
        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.
        """
        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 dutring 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')
        self.check_keycode()
        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):
        if not self.check_ec_capability(['lid']):
            raise error.TestNAError("Nothing needs to be tested on this device")

        logging.info("Shutdown and long delayed wake.")
        self.do_reboot_action((self.shutdown_and_wake,
                               self.long_delayed_wake))

        logging.info("Shutdown and short delayed wake.")
        self.do_reboot_action((self.shutdown_and_wake,
                               self.short_delayed_wake))

        logging.info("Check keycode and backlight.")
        self.check_state(self.check_keycode_and_backlight)
