# Copyright 2018 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 enum, error
from autotest_lib.server import test
from autotest_lib.server.cros.dark_resume_utils import DarkResumeUtils
from autotest_lib.server.cros.faft.config.config import Config as FAFTConfig
from autotest_lib.server.cros.servo import chrome_ec


# Possible states base can be forced into.
BASE_STATE = enum.Enum('ATTACH', 'DETACH', 'RESET')


 # List of wake sources expected to cause a full resume.
FULL_WAKE_SOURCES = ['PWR_BTN', 'LID_OPEN', 'BASE_ATTACH',
                     'BASE_DETACH', 'INTERNAL_KB']

# Max time taken by the system to resume.
RESUME_DURATION_SECS = 5

# Time in future after which RTC goes off.
RTC_WAKE_SECS = 30

# Max time taken by the system to suspend.
SUSPEND_DURATION_SECS = 5

# Time to allow lid transition to take effect.
WAIT_TIME_LID_TRANSITION_SECS = 5


class power_WakeSources(test.test):
    """
    Verify that wakes from input devices can trigger a full
    resume. Currently tests :
        1. power button
        2. lid open
        3. base attach
        4. base detach

    Also tests RTC triggers a dark resume.

    """
    version = 1

    def _after_resume(self, wake_source):
        """Cleanup to perform after resuming the device.

        @param wake_source: Wake source that has been tested.
        """
        if wake_source in ['BASE_ATTACH', 'BASE_DETACH']:
            self._force_base_state(BASE_STATE.RESET)

    def _before_suspend(self, wake_source):
        """Prep before suspend.

        @param wake_source: Wake source that is going to be tested.

        @return: Boolean, whether _before_suspend action is successful.
        """
        if wake_source == 'BASE_ATTACH':
            # Force detach before suspend so that attach won't be ignored.
            return self._force_base_state(BASE_STATE.DETACH)
        if wake_source == 'BASE_DETACH':
            # Force attach before suspend so that detach won't be ignored.
            return self._force_base_state(BASE_STATE.ATTACH)
        if wake_source == 'LID_OPEN':
            # Set the power policy for lid closed action to suspend.
            return self._host.run(
                'set_power_policy --lid_closed_action suspend',
                ignore_status=True).exit_status == 0
        return True

    def _force_base_state(self, base_state):
        """Send EC command to force the |base_state|.

        @param base_state: State to force base to. One of |BASE_STATE| enum.

        @return: False if the command does not exist in the current EC build.

        @raise error.TestFail : If base state change fails.
        """
        ec_cmd = 'basestate '
        ec_arg = {
            BASE_STATE.ATTACH: 'a',
            BASE_STATE.DETACH: 'd',
            BASE_STATE.RESET: 'r'
        }

        ec_cmd += ec_arg[base_state]

        try:
            self._ec.send_command(ec_cmd)
        except error.TestFail as e:
            if 'No control named' in str(e):
                # Since the command is added recently, this might not exist on
                # every board.
                logging.warning('basestate command does not exist on the EC. '
                                'Please verify the base state manually.')
                return False
            else:
                raise e
        return True

    def _is_valid_wake_source(self, wake_source):
        """Check if |wake_source| is valid for DUT.

        @param wake_source: wake source to verify.
        @return: True if |wake_source| is a valid wake source for this specific
            DUT
        """
        if wake_source.startswith('BASE'):
            if self._host.run('which hammerd', ignore_status=True).\
                exit_status == 0:
                # Smoke test to see if EC has support to reset base.
                return self._force_base_state(BASE_STATE.RESET)
        if wake_source == 'LID_OPEN':
            return self._dr_utils.host_has_lid()
        if wake_source == 'INTERNAL_KB':
            return self._faft_config.has_keyboard
        return True

    def _test_full_wake(self, wake_source):
        """Test if |wake_source| triggers a full resume.

        @param wake_source: wake source to test. One of |FULL_WAKE_SOURCES|.
        @return: True, if we are able to successfully test the |wake source|
            triggers a full wake.
        """
        is_success = True
        logging.info('Testing wake by %s triggers a '
                     'full wake when dark resume is enabled.', wake_source)
        if not self._before_suspend(wake_source):
            logging.error('Before suspend action failed for %s', wake_source)
            is_success = False
        else:
            count_before = self._dr_utils.count_dark_resumes()
            with self._dr_utils.suspend() as _:
                logging.info('DUT suspended! Waiting to resume...')
                # Wait at least |SUSPEND_DURATION_SECS| secs for the kernel to
                # fully suspend.
                time.sleep(SUSPEND_DURATION_SECS)
                self._trigger_wake(wake_source)
                # Wait at least |RESUME_DURATION_SECS| secs for the device to
                # resume.
                time.sleep(RESUME_DURATION_SECS)

                if not self._host.is_up():
                    logging.error('Device did not resume from suspend for %s',
                                  wake_source)
                    is_success = False

            count_after = self._dr_utils.count_dark_resumes()
            if count_before != count_after:
                logging.error('%s caused a dark resume.', wake_source)
                is_success = False
        self._after_resume(wake_source)
        return is_success

    def _test_rtc(self):
        """Suspend the device and test if RTC triggers a dark_resume.

        @return boolean, true if RTC alarm caused a dark resume.
        """

        logging.info('Testing RTC triggers dark resume when enabled.')

        count_before = self._dr_utils.count_dark_resumes()
        with self._dr_utils.suspend(RTC_WAKE_SECS) as _:
            logging.info('DUT suspended! Waiting to resume...')
            time.sleep(SUSPEND_DURATION_SECS + RTC_WAKE_SECS +
                       RESUME_DURATION_SECS)

            if not self._host.is_up():
                logging.error('Device did not resume from suspend for RTC')
                return False

        count_after = self._dr_utils.count_dark_resumes()
        if count_before != count_after - 1:
            logging.error(' RTC did not cause a dark resume.'
                          'count before = %d, count after = %d',
                          count_before, count_after)
            return False
        return True

    def _trigger_wake(self, wake_source):
        """Trigger wake using the given |wake_source|.

        @param wake_source : wake_source that is being tested.
            One of |FULL_WAKE_SOURCES|.
        """
        if wake_source == 'PWR_BTN':
            self._host.servo.power_short_press()
        elif wake_source == 'LID_OPEN':
            self._host.servo.lid_close()
            time.sleep(WAIT_TIME_LID_TRANSITION_SECS)
            self._host.servo.lid_open()
        elif wake_source == 'BASE_ATTACH':
            self._force_base_state(BASE_STATE.ATTACH)
        elif wake_source == 'BASE_DETACH':
            self._force_base_state(BASE_STATE.DETACH)
        elif wake_source == 'INTERNAL_KB':
            self._host.servo.ctrl_key()

    def cleanup(self):
        self._dr_utils.stop_resuspend_on_dark_resume(False)
        self._dr_utils.teardown()

    def initialize(self, host):
        """Initialize wake sources tests.

        @param host: Host on which the test will be run.
        """
        self._host = host
        self._dr_utils = DarkResumeUtils(host)
        self._dr_utils.stop_resuspend_on_dark_resume()
        self._ec = chrome_ec.ChromeEC(self._host.servo)
        self._faft_config = FAFTConfig(self._host.get_platform())

    def run_once(self):
        """Body of the test."""

        test_ws = set(ws for ws in FULL_WAKE_SOURCES if \
            self._is_valid_wake_source(ws))
        passed_ws = set(ws for ws in test_ws if self._test_full_wake(ws))
        failed_ws = test_ws.difference(passed_ws)
        skipped_ws = set(FULL_WAKE_SOURCES).difference(test_ws)

        if self._test_rtc():
            passed_ws.add('RTC')
        else:
            failed_ws.add('RTC')
        if len(passed_ws):
            logging.info('[%s] woke the device as expected.',
                         ''.join(str(elem) + ', ' for elem in passed_ws))
        if skipped_ws:
            logging.info('[%s] are not wake sources on this platform. '
                         'Please test manually if not the case.',
                         ''.join(str(elem) + ', ' for elem in skipped_ws))

        if len(failed_ws):
            raise error.TestFail(
                '[%s] wake sources did not behave as expected.'
                % (''.join(str(elem) + ', ' for elem in failed_ws)))
