# Copyright 2016 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, time

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

# platform_S3Cycle test timing constants
BEFORE_SUSPEND_WAIT_TIME_SECONDS = 10
BEFORE_RESUME_WAIT_TIME_SECONDS = 2
SUSPEND_WAIT_TIME_SECONDS = 5
LIDOPEN_WAIT_TIME_SECONDS = 2
POWER_STATE_RETRY_COUNT = 10

class platform_S3Cycle(FirmwareTest):
    '''
    Servo based S3 cycle test.
    '''
    version = 1

    def initialize(self, host, cmdline_args):
        dict_args = utils.args_to_dict(cmdline_args)
        self.faft_iterations = int(dict_args.get('faft_iterations', 1))
        super(platform_S3Cycle, self).initialize(host, cmdline_args)
        self.switcher.setup_mode('normal')

    def perform_s3_cycle(self):
        """
        Perform S3 suspend/resume cycle and check state transition.
        """
        resume_sources = ['powerbtn', 'lid', 'kbpress']
        for resume_source in resume_sources:
            time.sleep(BEFORE_SUSPEND_WAIT_TIME_SECONDS);
            self.perform_suspend()
            self.perform_resume(resume_source)

    def perform_suspend(self):
        """
        Perform suspend to mem and check state transition.
        """
        logging.info('== S3 suspend and check the state transition ==')
        # check S0 state transition
        if not self.wait_power_state('S0', POWER_STATE_RETRY_COUNT):
            raise error.TestFail('Platform failed to reach S0 state.')
        cmd = 'echo mem > /sys/power/state'
        block = False
        self.faft_client.system.run_shell_command(cmd, block)
        time.sleep(SUSPEND_WAIT_TIME_SECONDS);
        # check S3 state transition
        if not self.wait_power_state('S3', POWER_STATE_RETRY_COUNT):
            raise error.TestFail('Platform failed to reach S3 state.')

    def perform_resume(self, resume_source):
        """
        Perform resume with selected resume source and check state transition.
        @param resume_source(string):resume source option.
        """
        logging.info('== S3 resume and check the state transition ==')
        time.sleep(BEFORE_RESUME_WAIT_TIME_SECONDS);
        if resume_source == 'powerbtn':
            self.ec.send_command('powerbtn')
        elif resume_source == 'lid':
            self.ec.send_command('lidclose')
            time.sleep(LIDOPEN_WAIT_TIME_SECONDS);
            self.ec.send_command('lidopen')
        elif resume_source == 'kbpress':
            self.ec.key_press('<enter>')
        else:
            raise error.TestFail('Invalid resume source.')
        # check S0 state transition
        if not self.wait_power_state('S0', POWER_STATE_RETRY_COUNT):
            raise error.TestFail('Platform failed to reach S0 state.')

    def run_once(self):
        """Main test logic"""
        if not self.faft_config.chrome_ec or not self.check_ec_capability():
            raise error.TestNAError('Chrome EC is not supported on this device.')

        for i in xrange(self.faft_iterations):
            logging.info('== Running FAFT ITERATION %d/%s ==',i+1, self.faft_iterations)
            logging.info('S3 suspend/resume back and check state transition.')
            self.switcher.mode_aware_reboot('custom', self.perform_s3_cycle)

    def cleanup(self):
        self.ec.set_uart_regexp('None')
        # Test may failed before resume, wake the system.
        self.ec.send_command('powerbtn')
        # Perform a warm reboot as part of the cleanup.
        self._client.reboot()
        super(platform_S3Cycle, self).cleanup()
