# Copyright (c) 2011 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 autotest_lib.client.common_lib import error
from autotest_lib.server.cros.faft.firmware_test import FirmwareTest


class firmware_FwScreenPressPower(FirmwareTest):
    """
    Servo based power button triggered shutdown test during firmware screens.

    This test requires a USB disk plugged-in, which contains a Chrome OS test
    image (built by "build_image --test"). On runtime, this test triggers
    firmware screens (developer, remove, insert, yuck, and to_norm screens),
    and then presses the power button in order to power the machine down.
    """
    version = 1
    NEEDS_SERVO_USB = True

    SHORT_SHUTDOWN_CONFIRMATION_PERIOD = 0.1

    def wait_fw_screen_and_press_power(self):
        """Wait for firmware warning screen and press power button."""
        time.sleep(self.faft_config.firmware_screen)
        # While the firmware screen, the power button probing loop sleeps
        # 0.25 second on every scan. Use the normal delay (1.2 second) for
        # power press.

        if self.faft_config.is_detachable and self.faft_config.mode_switcher_type == 'menu_switcher':
            # Since power button has been overridden as a select button in the
            # fw screens for detachables, we can just skip this part of the test
            # and shut down the DUT using the power state controller instead.
            logging.info("Setting Power Off")
            self.servo.get_power_state_controller().power_off()
        else:
            # Otherwise use the power button
            logging.info("Pressing Power Button")
            self.servo.power_normal_press()

    def wait_longer_fw_screen_and_press_power(self):
        """Wait for firmware screen without timeout and press power button."""
        time.sleep(self.faft_config.dev_screen_timeout)
        self.wait_fw_screen_and_press_power()

    def wait_second_screen_and_press_power(self):
        """Wait and trigger a second screen and press power button."""
        self.switcher.trigger_dev_to_rec()
        self.wait_fw_screen_and_press_power()

    def wait_yuck_screen_and_press_power(self):
        """Insert corrupted USB for yuck screen and press power button."""
        # This USB stick will be removed in cleanup phase.
        self.servo.switch_usbkey('dut')
        time.sleep(self.faft_config.usb_plug)
        self.wait_longer_fw_screen_and_press_power()

    def initialize(self, host, cmdline_args):
        """Initialize the test"""
        super(firmware_FwScreenPressPower, self).initialize(host, cmdline_args)
        self.switcher.setup_mode('dev')
        self.setup_usbkey(True, host=True)
        usb_dev = self.servo.probe_host_usb_dev()
        # Corrupt the kernel of USB stick. It is needed for triggering a
        # yuck screen later.
        self.corrupt_usb_kernel(usb_dev)

    def cleanup(self):
        """Cleanup the test"""
        try:
            self.servo.switch_usbkey('host')
            usb_dev = self.servo.probe_host_usb_dev()
            # Restore the kernel of USB stick which is corrupted on setup phase.
            self.restore_usb_kernel(usb_dev)
        except Exception as e:
            logging.error("Caught exception: %s", str(e))
        super(firmware_FwScreenPressPower, self).cleanup()

    def run_once(self):
        """Main test logic"""
        if self.faft_config.mode_switcher_type not in (
                'keyboard_dev_switcher', 'tablet_detachable_switcher',
                'menu_switcher'):
            raise error.TestNAError("This test is only valid on devices with "
                                    "screens.")
        if not self.faft_config.has_powerbutton:
            raise error.TestNAError("This test is only valid on devices with "
                                    "power button.")

        logging.info(
                "Expected dev mode and reboot. "
                "When the next DEVELOPER SCREEN shown, press power button "
                "to make DUT shutdown.")
        self.check_state((self.checkers.crossystem_checker, {
                'devsw_boot': '1',
                'mainfw_type': 'developer',
        }))
        self.switcher.simple_reboot()
        self.run_shutdown_process(
                self.wait_fw_screen_and_press_power,
                post_power_action=self.switcher.bypass_dev_mode)
        self.switcher.wait_for_client()

        if self.faft_config.power_button_dev_switch:
            logging.info("Skipping TO_NORM screen test. The power button is "
                         "used to confirm DEV mode to NORM mode.")
        else:
            logging.info(
                    "Reboot. When the developer screen shown, press "
                    "enter key to trigger either TO_NORM screen (new) or "
                    "RECOVERY INSERT screen (old). Then press power button "
                    "to make DUT shutdown.")
            self.check_state((self.checkers.crossystem_checker, {
                    'devsw_boot': '1',
                    'mainfw_type': 'developer',
            }))
            self.switcher.simple_reboot()
            self.run_shutdown_process(
                    self.wait_second_screen_and_press_power,
                    post_power_action=self.switcher.bypass_dev_mode,
                    shutdown_timeout=self.SHORT_SHUTDOWN_CONFIRMATION_PERIOD)
            self.switcher.wait_for_client()

        logging.info("Request recovery boot. When the RECOVERY INSERT "
                     "screen shows, press power button to make DUT shutdown.")
        self.check_state((self.checkers.crossystem_checker, {
                'devsw_boot': '1',
                'mainfw_type': 'developer',
        }))
        self.servo.set_nocheck('power_state', 'rec')
        self.run_shutdown_process(
                self.wait_longer_fw_screen_and_press_power,
                post_power_action=self.switcher.bypass_dev_mode,
                shutdown_timeout=self.SHORT_SHUTDOWN_CONFIRMATION_PERIOD)
        self.switcher.wait_for_client()

        logging.info("Request recovery boot again. When the recovery "
                     "insert screen shows, insert a corrupted USB and trigger "
                     "a YUCK SCREEN. Then press power button to "
                     "make DUT shutdown.")
        self.check_state((self.checkers.crossystem_checker, {
                'devsw_boot': '1',
                'mainfw_type': 'developer',
        }))
        self.servo.set_nocheck('power_state', 'rec')
        self.run_shutdown_process(
                self.wait_yuck_screen_and_press_power,
                post_power_action=self.switcher.bypass_dev_mode,
                shutdown_timeout=self.SHORT_SHUTDOWN_CONFIRMATION_PERIOD)
        self.switcher.wait_for_client()

        logging.info("Switch back to normal mode.")
        self.check_state((self.checkers.crossystem_checker, {
                'devsw_boot': '1',
                'mainfw_type': 'developer',
        }))
        self.switcher.reboot_to_mode(to_mode='normal')

        logging.info("Expected normal mode and request recovery boot. "
                     "Because an USB stick is inserted, a RECOVERY REMOVE "
                     "screen shows. Press power button to make DUT shutdown.")
        self.check_state((self.checkers.crossystem_checker, {
                'devsw_boot': '0',
                'mainfw_type': 'normal',
        }))
        self.servo.set_nocheck('power_state', 'rec')
        self.run_shutdown_process(
                self.wait_longer_fw_screen_and_press_power,
                shutdown_timeout=self.SHORT_SHUTDOWN_CONFIRMATION_PERIOD)
        self.switcher.wait_for_client()

        logging.info("Check and done.")
        self.check_state((self.checkers.crossystem_checker, {
                'devsw_boot': '0',
                'mainfw_type': 'normal',
        }))
