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

import time
import logging
from threading import Timer

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


class firmware_ECPowerButton(FirmwareTest):
    """
    Servo based EC power button test.
    """
    version = 1

    # Delay between shutdown and wake by power button
    LONG_WAKE_DELAY = 13
    SHORT_WAKE_DELAY = 7

    # Delay between recovery screen and shutdown by power button
    RECOVERY_SCREEN_SHUTDOWN_DELAY = 3

    # Duration of holding down power button to shut down with powerd
    POWER_BUTTON_POWERD_DURATION = 6

    # Duration of holding down power button to shut down without powerd
    POWER_BUTTON_NO_POWERD_DURATION = 11

    # Duration of holding down power button to test ignoring power button press
    POWER_BUTTON_IGNORE_PRESS_DURATION = 0.2

    # Delay after pressing power button to check power state
    POWER_BUTTON_IGNORE_PRESS_DELAY = 5

    def initialize(self, host, cmdline_args):
        super(firmware_ECPowerButton, self).initialize(host, cmdline_args)
        # Short duration of holding down power button to power on
        self.POWER_BUTTON_SHORT_POWER_ON_DURATION = max(
                self.faft_config.hold_pwr_button_poweron, 0.05)
        # Long duration of holding down power button to power on
        self.POWER_BUTTON_LONG_POWER_ON_DURATION = max(
                self.faft_config.hold_pwr_button_poweron, 1)
        # Only run in normal mode
        self.switcher.setup_mode('normal')

    def kill_powerd(self):
        """Stop powerd on client."""
        self.faft_client.system.run_shell_command("stop powerd")

    def debounce_power_button(self):
        """Check if power button debouncing works.

        Press power button for a very short period and checks for power
        button keycode.
        """
        # Delay 3 seconds to ensure client machine is waiting for key press.
        # Press power button for only 10ms. Should be debounced.
        logging.info('ECPowerButton: debounce_power_button')
        Timer(3, self.servo.power_key, [0.001]).start()
        return self.faft_client.system.check_keys([116])

    def shutdown_and_wake(self,
                          shutdown_powerkey_duration,
                          wake_delay,
                          wake_powerkey_duration):
        """
        Shutdown the system by power button, delay, and then power on
        by power button again.
        """
        self.servo.power_key(shutdown_powerkey_duration)

        # Send a new line to wakeup EC from deepsleep,
        # it can happen if the EC console is not used for some time
        if wake_delay > 2:
            Timer(wake_delay - 1, self.ec.send_command, [""]).start()

        Timer(wake_delay,
              self.servo.power_key,
              [wake_powerkey_duration]).start()

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

        logging.info("Boot to recovery screen.")
        self.switcher.enable_rec_mode_and_reboot(usb_state='host')
        time.sleep(self.faft_config.firmware_screen)
        if self.get_power_state() != self.POWER_STATE_S0:
            raise error.TestFail("DUT didn't boot to recovery screen")

        logging.info("Shutdown by short power button press.")
        self.servo.power_key(self.faft_config.hold_pwr_button_poweron)
        time.sleep(self.RECOVERY_SCREEN_SHUTDOWN_DELAY)
        power_state = self.get_power_state()
        if (power_state != self.POWER_STATE_S5 and
            power_state != self.POWER_STATE_G3):
            raise error.TestFail("DUT didn't shutdown by "
                                 "short power button press")
        if self.ec.check_feature('EC_FEATURE_EFS2'):
            logging.info("Check if EC jumped to RW.")
            if not self.ec.check_ro_rw('RW'):
                raise error.TestFail("EC didn't jump to RW")

        logging.info("Boot by short power button press.")
        self.servo.power_key(self.faft_config.hold_pwr_button_poweron)
        self.switcher.wait_for_client()
        if self.get_power_state() != self.POWER_STATE_S0:
            raise error.TestFail("DUT didn't boot by short power button press")

        logging.info("Check system ignores short (200ms) power button press.")
        old_boot_id = self.get_bootid(retry=1)
        self.servo.power_key(self.POWER_BUTTON_IGNORE_PRESS_DURATION)
        time.sleep(self.POWER_BUTTON_IGNORE_PRESS_DELAY)
        power_state = self.get_power_state()
        new_boot_id = self.get_bootid(retry=1)
        if power_state != self.POWER_STATE_S0 or new_boot_id != old_boot_id:
            self._reset_client()
            raise error.TestFail("DUT shutdown from short power button press")

        logging.info("Shutdown when powerd is still running and wake from S5 "
                     "with short power button press.")
        if self.servo.is_localhost():
            self.check_state(self.debounce_power_button)
        self.switcher.mode_aware_reboot(
                'custom',
                lambda:self.shutdown_and_wake(
                        self.POWER_BUTTON_POWERD_DURATION,
                        self.SHORT_WAKE_DELAY,
                        self.POWER_BUTTON_SHORT_POWER_ON_DURATION))

        logging.info("Shutdown when powerd is stopped and wake from G3 "
                          "with short power button press.")
        self.kill_powerd()
        self.switcher.mode_aware_reboot(
                'custom',
                lambda:self.shutdown_and_wake(
                        self.POWER_BUTTON_NO_POWERD_DURATION,
                        self.LONG_WAKE_DELAY,
                        self.POWER_BUTTON_SHORT_POWER_ON_DURATION))

        logging.info("Shutdown when powerd is still running and wake from G3 "
                     "with long power button press.")
        self.switcher.mode_aware_reboot(
                'custom',
                lambda:self.shutdown_and_wake(
                        self.POWER_BUTTON_POWERD_DURATION,
                        self.LONG_WAKE_DELAY,
                        self.POWER_BUTTON_LONG_POWER_ON_DURATION))

        logging.info("Shutdown when powerd is stopped and wake from S5 "
                     "with long power button press.")
        self.kill_powerd()
        self.switcher.mode_aware_reboot(
                'custom',
                lambda:self.shutdown_and_wake(
                        self.POWER_BUTTON_NO_POWERD_DURATION,
                        self.SHORT_WAKE_DELAY,
                        self.POWER_BUTTON_LONG_POWER_ON_DURATION))
