# 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 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 = 10

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

        # Duration of holding down power button to shut down without powerd
        self.POWER_BUTTON_NO_POWERD_DURATION = max(
                self.faft_config.hold_pwr_button_nopowerd_shutdown, 11)
        # 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')
        self.has_internal_display = host.has_internal_display()

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

        if self.has_internal_display:
            logging.info("Display connected, 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 200ms power "
                                     "button press")
        else:
            logging.info("No display connected, check system shuts down from "
                         "short 200ms power button check.")
            self.servo.power_key(self.POWER_BUTTON_IGNORE_PRESS_DURATION)
            time.sleep(self.POWER_BUTTON_IGNORE_PRESS_DELAY)
            power_state = self.get_power_state()
            logging.info("Power state = %s", power_state)
            if (power_state != self.POWER_STATE_S5 and
                power_state != self.POWER_STATE_G3):
                self._reset_client()
                raise error.TestFail("DUT didn't shutdown 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:
                self._reset_client()
                raise error.TestFail("DUT didn't boot by 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() and self.has_internal_display:
            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))
