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

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


class firmware_PDPowerSwap(FirmwareTest):
    """
    Servo based USB PD power role swap test.

    Pass critera is all power role swaps are successful if the DUT
    is dualrole capable. If not dualrole, then pass criteria is
    the DUT sending a reject message in response to swap request.

    """

    version = 1
    PD_ROLE_DELAY = 1
    PD_CONNECT_DELAY = 10
    # Should be an even number; back to the original state at the end
    POWER_SWAP_ITERATIONS = 10

    def _set_pdtester_power_role_to_src(self):
        """Force PDTester to act as a source

        @returns True if PDTester power role is source, false otherwise
        """
        PDTESTER_SRC_VOLTAGE = 20
        self.pdtester.charge(PDTESTER_SRC_VOLTAGE)
        # Wait for change to take place
        time.sleep(self.PD_CONNECT_DELAY)
        # Current PDTester power role should be source
        return self.pdtester_port.is_src()

    def _send_power_swap_get_reply(self, port):
        """Send power swap request, get PD control msg reply

        The PD console debug mode is enabled prior to sending
        a pd power role swap request message. This allows the
        control message reply to be extracted. The debug mode
        is disabled prior to exiting.

        @param port: pd device object

        @returns: PD control header message
        """
        # Enable PD console debug mode to show control messages
        port.utils.enable_pd_console_debug()
        cmd = 'pd %d swap power' % port.port
        m = port.utils.send_pd_command_get_output(cmd, ['RECV\s([\w]+)'])
        ctrl_msg = int(m[0][1], 16) & port.utils.PD_CONTROL_MSG_MASK
        port.utils.disable_pd_console_debug()
        return ctrl_msg

    def _attempt_power_swap(self, direction):
        """Perform a power role swap request

        Initiate a power role swap request on either the DUT or
        PDTester depending on the direction parameter. The power
        role swap is then verified to have taken place.

        @param direction: rx or tx from the DUT perspective

        @returns True if power swap is successful
        """
        # Get DUT current power role
        dut_pr = self.dut_port.get_pd_state()
        if direction == 'rx':
            port = self.pdtester_port
        else:
            port = self.dut_port
        # Send power swap request
        self._send_power_swap_get_reply(port)
        time.sleep(self.PD_CONNECT_DELAY)
        # Get PDTester power role
        pdtester_pr = self.pdtester_port.get_pd_state()
        if self.dut_port.is_src(dut_pr) and self.pdtester_port.is_src(pdtester_pr):
            return True
        elif self.dut_port.is_snk(dut_pr) and self.pdtester_port.is_snk(pdtester_pr):
            return True
        else:
            return False

    def _test_power_swap_reject(self):
        """Verify that a power swap request is rejected

        This tests the case where the DUT isn't in dualrole mode.
        A power swap request is sent by PDTester, and then
        the control message checked to ensure the request was rejected.
        In addition, the connection state is verified to not have
        changed.
        """
        # Get current DUT power role
        dut_power_role = self.dut_port.get_pd_state()
        # Send swap command from PDTester and get reply
        ctrl_msg = self._send_power_swap_get_reply(self.pdtester_port)
        if ctrl_msg != self.dut_port.utils.PD_CONTROL_MSG_DICT['Reject']:
            raise error.TestFail('Power Swap Req not rejected, returned %r' %
                                 ctrl_msg)
        # Get DUT current state
        pd_state = self.dut_port.get_pd_state()
        if pd_state != dut_power_role:
            raise error.TestFail('PD not connected! pd_state = %r' %
                                 pd_state)

    def _test_one_way_power_swap_in_suspend(self):
        """Verify SRC-to-SNK power role swap on DUT PD port in S0ix/S3

        Set the DUT power role to source and then suspend the DUT.
        Verify SRC-to-SNK power role request from the PD tester works,
        while SNK-to-SRC power role request fails. Note that this is
        Chrome OS policy decision, not part of the PD spec.

        When DUT doesn't provide power in suspend, set DUT power role
        to sink, supend DUT and check if SNK-to-SRC power role request fails.

        """
        # Ensure DUT PD port is sourcing power.
        time.sleep(self.PD_CONNECT_DELAY)
        if self.faft_config.dut_can_source_power_in_suspend:
            if not self.dut_port.is_src():
                if self._attempt_power_swap('rx') == False or not self.dut_port.is_src():
                    raise error.TestFail('Fail to set DUT power role to source.')

            self.set_ap_off_power_mode('suspend')

            new_state = self.dut_port.get_pd_state()
            if not self.dut_port.is_src(new_state):
                raise error.TestFail('DUT power role changed to %s '
                        'during S0-to-S3 transition!' % new_state)

            # If the DUT PD port supports DRP in S0, it should supports SRC-to-SNK
            # power role swap in suspend mode. The other way around (SNK-to-SRC) in
            # suspend mode should fail.
            logging.info('Request a SRC-to-SNK power role swap to DUT PD port '
                         'in suspend mode. Expect to succeed.')
            if self._attempt_power_swap('rx') == False:
                raise error.TestFail('SRC-to-SNK power role swap failed.')

            # If we define AC insertion as a wake source for this board, the
            # SRC-to-SNK power role swap would wake up the DUT. In this case,
            # we need to suspend the DUT again to proceed the test.
            if self.wait_power_state(self.POWER_STATE_S0,
                                     self.DEFAULT_PWR_RETRIES):
                self.set_ap_off_power_mode('suspend')
        else:
            # If DUT can't source power in suspend we are going to test only if
            # SNK-to-SRC transition fails, so make sure that port acts as sink
            logging.info('DUT is not sourcing power in suspend - '
                    'skip verification if SRC-to-SNK power swap works')
            if not self.dut_port.is_snk():
                if self._attempt_power_swap('rx') == False or not self.dut_port.is_snk():
                    raise error.TestFail('Fail to set DUT power role to sink.')

            self.set_ap_off_power_mode('suspend')

            new_state = self.dut_port.get_pd_state()
            if not self.dut_port.is_snk(new_state):
                raise error.TestFail('DUT power role changed to %s '
                        'during S0-to-S3 transition!' % new_state)

        logging.info('Request a SNK-to-SRC power role swap to DUT PD port '
                     'in suspend mode. Expect to fail.')
        self._test_power_swap_reject()

        self.restore_ap_on_power_mode()

    def initialize(self, host, cmdline_args, flip_cc=False, dts_mode=False,
                   init_power_mode=None):
        super(firmware_PDPowerSwap, self).initialize(host, cmdline_args)
        self.setup_pdtester(flip_cc, dts_mode, min_batt_level=10)
        # Only run in normal mode
        self.switcher.setup_mode('normal')
        if init_power_mode:
            # Set the DUT to suspend (S3) or shutdown (G3/S5) mode
            self.set_ap_off_power_mode(init_power_mode)
        # Turn off console prints, except for USBPD.
        self.usbpd.enable_console_channel('usbpd')

    def cleanup(self):
        if hasattr(self, 'pd_port'):
            # Restore DUT dual role operation
            self.dut_port.drp_set('on')
        if hasattr(self, 'pdtester_port'):
            # Set connection back to default arrangement
            self.pdtester_port.drp_set('off')

        if hasattr(self, 'pd_port') and hasattr(self, 'pdtester_port'):
            # Fake-disconnect to restore the original power role
            self.pdtester_port.utils.send_pd_command('fakedisconnect 100 1000')

        self.usbpd.send_command('chan 0xffffffff')
        self.restore_ap_on_power_mode()
        super(firmware_PDPowerSwap, self).cleanup()

    def run_once(self):
        """Execute Power Role swap test.

        1. Verify that pd console is accessible
        2. Verify that DUT has a valid PD contract and connected to PDTester
        3. Determine if DUT is in dualrole mode
        4. If dualrole mode is not supported, verify DUT rejects power swap
           request. If dualrole mode is supported, test power swap (tx/rx) in
           S0 and one-way power swap (SRC-to-SNK on DUT PD port) in S3/S0ix.
           Then force DUT to be sink or source only and verify rejection of
           power swap request.

        """
        # Create list of available UART consoles
        consoles = [self.usbpd, self.pdtester]
        port_partner = pd_device.PDPortPartner(consoles)

        # Identify a valid test port pair
        port_pair = port_partner.identify_pd_devices()
        if not port_pair:
            raise error.TestFail('No PD connection found!')

        for port in port_pair:
            if port.is_pdtester:
                self.pdtester_port = port
            else:
                self.dut_port = port

        dut_connect_state = self.dut_port.get_pd_state()
        logging.info('Initial DUT connect state = %s', dut_connect_state)

        # Get DUT dualrole status
        if self.dut_port.is_drp() == False:
            # DUT does not support dualrole mode, power swap
            # requests to the DUT should be rejected.
            logging.info('Power Swap support not advertised by DUT')
            self._test_power_swap_reject()
            logging.info('Power Swap request rejected by DUT as expected')
        else:
            if self.get_power_state() != 'S0':
                raise error.TestFail('If the DUT is not is S0, the DUT port '
                        'shouldn\'t claim dualrole is enabled.')
            # Start with PDTester as source
            if self._set_pdtester_power_role_to_src() == False:
                raise error.TestFail('PDTester not set to source')
            # DUT is dualrole in dual role mode. Test power role swap
            # operation intiated both by the DUT and PDTester.
            success = 0
            for attempt in xrange(self.POWER_SWAP_ITERATIONS):
                if attempt & 1:
                    direction = 'rx'
                else:
                    direction = 'tx'
                if self._attempt_power_swap(direction):
                    success += 1
                new_state = self.dut_port.get_pd_state()
                logging.info('New DUT power role = %s', new_state)

            if success != self.POWER_SWAP_ITERATIONS:
                raise error.TestFail('Failed %r power swap attempts' %
                                     (self.POWER_SWAP_ITERATIONS - success))

            self._test_one_way_power_swap_in_suspend()

            # Force DUT to only support current power role
            if self.dut_port.is_src(new_state):
                dual_mode = 'src'
            else:
                dual_mode = 'snk'

            # Save current dual role setting
            current_dual_role = self.dut_port.drp_get()

            try:
                logging.info('Setting dualrole mode to %s', dual_mode)
                self.dut_port.drp_set(dual_mode)
                time.sleep(self.PD_ROLE_DELAY)
                # Expect behavior now is that DUT will reject power swap
                self._test_power_swap_reject()
                logging.info('Power Swap request rejected by DUT as expected')
            finally:
                # Restore dual role setting
                self.dut_port.drp_set(current_dual_role)
