# 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 logging
import time

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


class firmware_ECWakeSource(FirmwareTest):
    """
    Servo based EC wake source test.
    """
    version = 1

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

    def cleanup(self):
        # Restore the lid_open switch in case the test failed in the middle.
        self.servo.set('lid_open', 'yes')
        super(firmware_ECWakeSource, self).cleanup()

    def hibernate_and_wake_by_power_button(self):
        """Shutdown to G2/S5, then hibernate EC. Finally, wake by power button."""
        self.faft_client.System.RunShellCommand("shutdown -H now")
        self.switcher.wait_for_client_offline()
        self.ec.send_command("hibernate 1000")
        time.sleep(self.WAKE_DELAY)
        self.servo.power_short_press()

    def run_once(self, host):
        """Runs a single iteration of the test."""
        # TODO(victoryang): make this test run on both x86 and arm
        if not self.check_ec_capability(['x86', 'lid']):
            raise error.TestNAError("Nothing needs to be tested on this device")

        # Login as a normal user and stay there, such that closing lid triggers
        # suspend, instead of shutdown.
        autotest_client = autotest.Autotest(host)
        autotest_client.run_test("desktopui_SimpleLogin",
                                 exit_without_logout=True)

        original_boot_id = host.get_boot_id()

        logging.info("Suspend and wake by power button.")
        self.suspend()
        self.switcher.wait_for_client_offline()
        self.servo.power_normal_press()
        self.switcher.wait_for_client()

        logging.info("Suspend and wake by lid switch.")
        self.suspend()
        self.switcher.wait_for_client_offline()
        self.servo.set('lid_open', 'no')
        time.sleep(self.LID_DELAY)
        self.servo.set('lid_open', 'yes')
        self.switcher.wait_for_client()

        logging.info("Close lid to suspend and wake by lid switch.")
        self.servo.set('lid_open', 'no')
        # Expect going to suspend, not pingable
        self.switcher.wait_for_client_offline()
        time.sleep(self.LID_DELAY)
        self.servo.set('lid_open', 'yes')
        self.switcher.wait_for_client()

        boot_id = host.get_boot_id()
        if boot_id != original_boot_id:
            raise error.TestFail('Different boot_id. Unexpected reboot.')

        if self.servo.running_through_ccd():
            logging.info("Using CCD, ignore waking by power button.")
        else:
            logging.info("EC hibernate and wake by power button.")
            self.hibernate_and_wake_by_power_button()
            self.switcher.wait_for_client()
