# Copyright 2019 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.cr50_test import Cr50Test
from autotest_lib.server.cros.servo import servo


class firmware_Cr50DeferredECReset(Cr50Test):
    """Verify EC_RST_L stays asserted only if all conditions below are True.
    (1) System got 'Power-On reset'.
    (2) RDD cable is connected.
    (3) The power button is held.

    After this, EC_RST_L should be deasserted as soon as the power button
    gets released.

    Attributes
        version: test version number
        CUTOFF_DELAY: duration in second to keep cr50 powered off,
        PD_SETTLE_TIME: duration in second to wait PD to be stable
        HAS_CR50_RESET_ODL: boolean if 'cr50_reset_odl' control is available
    """
    version = 1
    CUTOFF_DELAY = 10
    PD_SETTLE_TIME = 3
    HAS_CR50_RESET_ODL = False

    def cr50_power_on_reset(self):
        """Perform a power-on-reset on cr50.
           If cr50_reset_odl control is available, then use it.
           Otherwise, disconnect and reconnect battery and power source.
        """
        if self.HAS_CR50_RESET_ODL:
            self.servo.set('cr50_reset_odl', 'on')

            time.sleep(self.CUTOFF_DELAY)

            self.servo.set('cr50_reset_odl', 'off')
        else:
            # Stop power delivery to dut
            logging.info('Stop charging')
            self.servo.set('servo_v4_role', 'snk')

            # Battery Cutoff
            logging.info('Cut battery off')
            self.ec.send_command('cutoff')

            time.sleep(self.CUTOFF_DELAY)

            # Enable power delivery to dut
            logging.info('Start charging')
            self.servo.set('servo_v4_role', 'src')

        time.sleep(self.PD_SETTLE_TIME)

    def ac_is_plugged_in(self):
        """Check if AC is plugged.

        Returns:
            True if AC is plugged, or False otherwise.
        """

        rv = self.ec.send_command_get_output('chgstate',
                                             [r'ac\s*=\s*(0|1)\s*'])[0][1]
        return rv == '1'

    def initialize(self, host, cmdline_args, full_args):
        """Initialize the test and check if cr50 exists, DTS is controllable,
           and power delivery mode and power button is adjustable.

        Raises:
            TestFail: If test initialization setup fails.
            TestNAError: If the dut is not proper for this test for its RDD
                         recognition problem.
        """
        super(firmware_Cr50DeferredECReset, self).initialize(host, cmdline_args,
                full_args)
        if not hasattr(self, 'cr50'):
            raise error.TestNAError('Test can only be run on devices with '
                                    'access to the Cr50 console')
        if not self.cr50.servo_dts_mode_is_valid():
            raise error.TestNAError('Need working servo v4 DTS control')
        self.dts_restore = self.servo.get_dts_mode()

        # Fast open cr50 and check if testlab is enabled.
        self.fast_open(enable_testlab=True)
        if not self.cr50.testlab_is_on():
            raise error.TestNAError('Cr50 testlab mode is not enabled')

        # Check 'rdd_leakage' is marked in cr50 capability.
        if self.check_cr50_capability(['rdd_leakage']):
            self.rdd_leakage = True
            logging.warn('RDD leakage is marked in cr50 cap config')
        else:
            self.rdd_leakage = False

        # Test if the power button is adjustable.
        self.servo.set('pwr_button', 'press')
        self.servo.set('pwr_button', 'release')

        # Check if 'cr50_reset_odl' controlis available.
        try:
            self.servo.get('cr50_reset_odl')
            self.HAS_CR50_RESET_ODL = True
        except error.TestFail:
            self.HAS_CR50_RESET_ODL = False

            # Test the external power delivery
            self.servo.set('servo_v4_role', 'snk')
            time.sleep(self.PD_SETTLE_TIME)

            if self.ac_is_plugged_in():
                raise error.TestFail('Failed to set servo_v4_role sink')

            # Test stopping the external power delivery
            self.servo.set('servo_v4_role', 'src')
            time.sleep(self.PD_SETTLE_TIME)

            if not self.ac_is_plugged_in():
                raise error.TestFail('Failed to set servo_v4_role source')

        # Check if the dut has any RDD recognition issue.
        # First, cut off power source and hold the power button.
        #        disable RDD connection.
        self.servo.set_dts_mode('off')
        self.servo.set('pwr_button', 'press')
        self.cr50_power_on_reset()
        try:
            #  Third, check if the rdd status is disconnected.
            #         If not, terminate the test.
            ccdstate = self.cr50.get_ccdstate()

            if (ccdstate['Rdd'].lower() != 'disconnected') != self.rdd_leakage:
                raise error.TestError('RDD leakage does not match capability'
                                      ' configuration.')
        finally:
            self.servo.set_dts_mode(self.dts_restore)
            self.servo.set_nocheck('pwr_button', 'release')
            time.sleep(self.PD_SETTLE_TIME)

            self.servo.power_short_press()            # Wake up AP

        logging.info('Initialization is done')

    def check_ecrst_asserted(self, expect_assert):
        """Ask CR50 whether EC_RST_L is asserted or deasserted.

        Args:
            expect_assert: True if it is expected asserted.
                           False otherwise.

        Raises:
            TestFail: if ecrst value is not as expected.
        """

        # If the console is responsive, then the EC is awake.
        expected_txt = 'asserted' if expect_assert else 'deasserted'
        logging.info('Checking if ecrst is %s', expected_txt)

        try:
            rv = self.cr50.send_command_get_output('ecrst',
                                        [r'EC_RST_L is (%s)' % expected_txt])
            logging.info(rv)
        except error.TestError as e:
            raise error.TestFail(str(e))

    def ping_ec(self, expect_response):
        """Check if EC is running and responding.

        Args:
            expect_response: True if EC should respond
                             False otherwise.
        Raises:
            TestFail: if ec responsiveness is not as same as expected.
        """
        try:
            logging.info('Checking if ec is %sresponsive',
                         '' if expect_response else 'not ')
            rv = self.ec.send_command_get_output('help', ['.*>'])[0].strip()
        except servo.UnresponsiveConsoleError as e:
            logging.info(str(e))
            return
        else:
            if not expect_response:
                logging.error('EC should not respond')
                raise error.TestFail(rv)

    def test_deferred_ec_reset(self, power_button_hold, rdd_enable):
        """Do a power-on reset, and check if EC responds.

        Args:
            power_button_hold: True if it should be pressed on a system reset.
                               False otherwise.
            rdd_enable: True if RDD should be detected on a system reset.
                        False otherwise.
        """

        # If the board has a rdd leakage issue, RDD shall be detected
        # always in G3. EC_RST will be asserted if the power_button is
        # being presed in this test.
        expect_ec_response = not (power_button_hold and
                                  (rdd_enable or self.rdd_leakage))
        logging.info('Test deferred_ec_reset starts')
        logging.info('Power button held    : %s', power_button_hold)
        logging.info('RDD connection       : %s', rdd_enable)
        logging.info('RDD leakage          : %s', self.rdd_leakage)
        logging.info('Expected EC response : %s', expect_ec_response)

        try:
            # enable RDD Connection (or disable) before power-on-reset
            self.servo.set_dts_mode('on' if rdd_enable else 'off')

            # Set power button before the dut loses power,
            # because the power button value cannot be changed during power-off.
            self.servo.set('pwr_button',
                           'press' if power_button_hold else 'release')

            # Do a power-on-reset on CR50.
            self.cr50_power_on_reset()

            # Wait for a while
            wait_sec = 30
            logging.info('waiting for %d seconds', wait_sec)
            time.sleep(wait_sec)

            # Check if EC_RST_L is asserted and EC is on.
            # (or EC_RST_L deasserted and EC off)
            self.check_ecrst_asserted(not expect_ec_response)
            self.ping_ec(expect_ec_response)

            # Release power button
            logging.info('Power button released')
            self.servo.set('pwr_button', 'release')
            time.sleep(self.PD_SETTLE_TIME)

            # Check if EC_RST_L is deasserted and EC is on.
            self.check_ecrst_asserted(False)
            self.ping_ec(True)

        finally:
            if self.HAS_CR50_RESET_ODL:
                self.servo.set_nocheck('cr50_reset_odl', 'off')
            else:
                self.servo.set_nocheck('servo_v4_role', 'src')

            self.servo.set_dts_mode(self.dts_restore)
            time.sleep(1)

            # Press power button to wake up AP, and releases it soon
            # in any cases.
            self.servo.power_short_press()

    def run_once(self):
        """Test deferred EC reset feature. """

        # Release power button and disable RDD on power-on reset.
        # EC should be running.
        self.test_deferred_ec_reset(power_button_hold=False, rdd_enable=False)

        # Release power button but enable RDD on power-on reset.
        # EC should be running.
        self.test_deferred_ec_reset(power_button_hold=False, rdd_enable=True)

        # Hold power button but disable RDD on power-on reset.
        # EC should be running.
        self.test_deferred_ec_reset(power_button_hold=True, rdd_enable=False)

        # Hold power button and enable RDD on power-on reset.
        # EC should not be running.
        self.test_deferred_ec_reset(power_button_hold=True, rdd_enable=True)

        logging.info('Test is done')
