# Copyright 2020 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.

"""Bluetooth tests to check controller role support

In preparation for Nearby features, we need to verify that our device
controllers support the LE connection roles that we will require
"""

from __future__ import absolute_import

import logging
import threading
import time

import common
from autotest_lib.server.cros.bluetooth import advertisements_data
from autotest_lib.server.cros.bluetooth import bluetooth_adapter_tests

DEFAULT_MIN_ADV_INTERVAL = 200
DEFAULT_MAX_ADV_INTERVAL = 500


class bluetooth_AdapterControllerRoleTests(
        bluetooth_adapter_tests.BluetoothAdapterTests):
    """Bluetooth controller role tests.

    This class comprises a number of test cases to verify our controllers
    support the minimum requirements for LE connection states.
    """

    def pair_adapter_to_device(self, device):
        """Pairs to device, then disconnects

        For our Nearby tests, we use a peer emulating a HID device to act as
        the Nearby device. Since HID profile requires bonding for connection to
        occur, this function exchanges the bonding information as a test
        prerequisite so the Nearby device can later connected

        @param device: handle to peripheral object
        """

        self.test_discover_device(device.address)
        time.sleep(self.TEST_SLEEP_SECS)
        self.test_pairing(device.address, device.pin, trusted=True)
        self.test_disconnection_by_adapter(device.address)


    def connect_and_test_secondary_device(self, device, secondary_test_func):
        """Creates connection to a secondary device and tests it

        @param device: handle to peripheral object
        @param secondary_test_func: function handle to test connection
        """
        logging.info('Setting up secondary device')
        self.test_discover_device(device.address)
        self.test_pairing(device.address, device.pin, trusted=True)
        time.sleep(self.TEST_SLEEP_SECS)
        self.test_connection_by_adapter(device.address)
        time.sleep(self.TEST_SLEEP_SECS)
        secondary_test_func(device)


    def _receiver_discovery_async(self, device):
        """Asynchronously discovers and begins advertising from peer

        We want to verify that the DUT is scanning and advertising at the same
        time. This function returns a thread that waits, discovers the desired
        device, and then starts advertising back to emulate a Nearby Receiver
        device.

        @param device: handle to peripheral object

        @returns threading.Thread object with receiver discovery task
        """

        def _action_receiver_discovery():
            time.sleep(3)
            self.test_discover_by_device(device)
            self.test_device_set_discoverable(device, True)

        thread = threading.Thread(target=_action_receiver_discovery)
        return thread

    # ---------------------------------------------------------------
    # Definitions of controller readiness tests
    # ---------------------------------------------------------------

    ### General test for controller in secondary role
    def controller_secondary_role_test(self, primary_device, primary_test_func,
                                       secondary_info=None):
        """Advertise from DUT and verify we can handle connection as secondary

        Optional secondary device arguments allows us to try test with existing
        connection, or to establish new secondary connection during test

        @param primary_device: primary device of connection test
        @param primary_test_func: function to test connection to primary
        @param secondary_info: Optional tuple with structure
            (secondary_device_handle, secondary_test_func, use):
            secondary_device_handle: peer device to test with
            secondary_test_func: function handle to run connection test
            device_use: 'pre' - device should be connected before test runs - or
                        'mid' - device should be connected during test
        """

        #
        # Due to crbug/946835, some messages does not reach btmon
        # causing our tests to fails. This is seen on kernel 3.18 and lower.
        # Remove this check when the issue is fixed
        # TODO(crbug/946835)
        #
        self.is_supported_kernel_version(self.host.get_kernel_version(),
                                         '3.19',
                                         'Test cannnot proceed on this'
                                         'kernel due to crbug/946835 ')

        self.bluetooth_le_facade = self.bluetooth_facade

        if secondary_info is not None:
            (secondary_device_handle, secondary_test_func,
                    device_use) = secondary_info

        # Start fresh, remove DUT from peer's known devices
        primary_device.RemoveDevice(self.bluetooth_facade.address)

        # Pair the primary device first - necessary for later connection to
        # secondary device
        self.pair_adapter_to_device(primary_device)
        self.test_device_set_discoverable(primary_device, False)

        # If test requires it, connect and test secondary device
        if secondary_info is not None and device_use == 'pre':
            self.connect_and_test_secondary_device(
                secondary_device_handle, secondary_test_func)

        # Register and start advertising instance
        # We ignore failure because the test isn't able to verify the min/max
        # advertising intervals, but this is ok.
        self.test_reset_advertising()
        self.test_set_advertising_intervals(DEFAULT_MIN_ADV_INTERVAL,
                                            DEFAULT_MAX_ADV_INTERVAL)
        self.test_register_advertisement(advertisements_data.ADVERTISEMENTS[0],
                                         1, DEFAULT_MIN_ADV_INTERVAL,
                                         DEFAULT_MAX_ADV_INTERVAL)

        # Discover DUT from peer
        self.test_discover_by_device(primary_device)
        time.sleep(self.TEST_SLEEP_SECS)

        # Connect to DUT from peer, putting DUT in secondary role
        self.test_connection_by_device(primary_device)

        # If test requires it, connect and test secondary device
        if secondary_info is not None and device_use == 'mid':
            self.connect_and_test_secondary_device(
                secondary_device_handle, secondary_test_func)

        # Try transferring data over connection
        primary_test_func(primary_device)

        # Handle cleanup of connected devices
        if secondary_info is not None:
            self.test_disconnection_by_adapter(secondary_device_handle.address)

        self.test_disconnection_by_device(primary_device)
        self.test_reset_advertising()

    ### Nearby sender role test

    def nearby_sender_role_test(self, nearby_device, nearby_device_test_func,
                                secondary_info=None):
        """Test Nearby Sender role

        Optional secondary device arguments allows us to try test with existing
        connection, or to establish new secondary connection during test

        @param nearby_device: Device acting as Nearby Receiver in test
        @param nearby_device_test_func: function to test connection to device
        @param secondary_info: Optional tuple with structure
            (secondary_device_handle, secondary_test_func, use):
            secondary_device_handle: peer device to test with
            secondary_test_func: function handle to run connection test
            device_use: 'pre' - device should be connected before test runs - or
                        'mid' - device should be connected during test
        """

        #
        # Due to crbug/946835, some messages does not reach btmon
        # causing our tests to fails. This is seen on kernel 3.18 and lower.
        # Remove this check when the issue is fixed
        # TODO(crbug/946835)
        #
        self.is_supported_kernel_version(self.host.get_kernel_version(),
                                         '3.19',
                                         'Test cannnot proceed on this'
                                         'kernel due to crbug/946835 ')

        self.bluetooth_le_facade = self.bluetooth_facade

        if secondary_info is not None:
            (secondary_device_handle, secondary_test_func,
                    device_use) = secondary_info

        # Start fresh, remove DUT from nearby device
        nearby_device.RemoveDevice(self.bluetooth_facade.address)

        # Pair the nearby device first - necessary for later connection to
        # secondary device
        self.pair_adapter_to_device(nearby_device)

        # We don't want peer advertising until it hears our broadcast
        self.test_device_set_discoverable(nearby_device, False)

        # If test requires it, connect and test secondary device
        if secondary_info is not None and device_use == 'pre':
            self.connect_and_test_secondary_device(
                secondary_device_handle, secondary_test_func)

        # Register and start non-connectable advertising instance
        # We ignore failure because the test isn't able to verify the min/max
        # advertising intervals, but this is ok.
        self.test_reset_advertising()
        self.test_set_advertising_intervals(DEFAULT_MIN_ADV_INTERVAL,
                                            DEFAULT_MAX_ADV_INTERVAL)

        # For now, advertise connectable advertisement. If we use a broadcast
        # advertisement, the Pi can't resolve the address and
        # test_discover_by_device will fail
        self.test_register_advertisement(
            advertisements_data.ADVERTISEMENTS[0], 1,
            DEFAULT_MIN_ADV_INTERVAL, DEFAULT_MAX_ADV_INTERVAL)

        # Second thread runs on peer, delays, discovers DUT, and then advertises
        # itself back
        peer_discover = self._receiver_discovery_async(nearby_device)
        peer_discover.start()

        # Verify that we correctly receive advertisement from nearby device
        self.test_receive_advertisement(address=nearby_device.address,
                                        timeout=30)

        # Make sure peer thread completes
        peer_discover.join()

        # Connect to peer from DUT
        self.test_connection_by_adapter(nearby_device.address)

        # TODO(b/164131633) On 4.4 kernel, sometimes the input device is not
        # created if we connect a second device too quickly
        time.sleep(self.TEST_SLEEP_SECS)

        # If test requires it, connect and test secondary device
        if secondary_info is not None and device_use == 'mid':
            self.connect_and_test_secondary_device(
                secondary_device_handle, secondary_test_func)

        time.sleep(self.TEST_SLEEP_SECS)

        # Try data test with nearby device
        nearby_device_test_func(nearby_device)

        # Handle cleanup of connected devices
        if secondary_info is not None:
            self.test_disconnection_by_adapter(secondary_device_handle.address)

        self.test_disconnection_by_adapter(nearby_device.address)
        self.test_reset_advertising()

    # Nearby receiver role test

    def nearby_receiver_role_test(self, nearby_device, nearby_device_test_func,
                                  secondary_info=None):
        """Test Nearby Receiver role

        Optional secondary device arguments allows us to try test with existing
        connection, or to establish new secondary connection during test

        @param nearby_device: Device acting as Nearby Sender in test
        @param nearby_device_test_func: function to test connection to device
        @param secondary_info: Optional tuple with structure
            (secondary_device_handle, secondary_test_func, use):
            secondary_device_handle: peer device to test with
            secondary_test_func: function handle to run connection test
            device_use: 'pre' - device should be connected before test runs - or
                        'mid' - device should be connected in middle of test,
                                during advertisement
                        'end' - device should be connected at end of test, when
                                already connected to Nearby device
        """

        #
        # Due to crbug/946835, some messages does not reach btmon
        # causing our tests to fails. This is seen on kernel 3.18 and lower.
        # Remove this check when the issue is fixed
        # TODO(crbug/946835)
        #
        self.is_supported_kernel_version(self.host.get_kernel_version(),
                                         '3.19',
                                         'Test cannnot proceed on this'
                                         'kernel due to crbug/946835 ')

        self.bluetooth_le_facade = self.bluetooth_facade

        if secondary_info is not None:
            (secondary_device_handle, secondary_test_func,
                    device_use) = secondary_info

        # Start fresh, remove device peer
        nearby_device.RemoveDevice(self.bluetooth_facade.address)

        # If test requires it, connect and test secondary device
        if secondary_info is not None and device_use == 'pre':
            self.connect_and_test_secondary_device(
                secondary_device_handle, secondary_test_func)

        # Verify that we correctly receive advertisement from peer
        # TODO ideally, peer would be broadcasting non-connectable adv with
        # 0xFE2C data, but this is not implemented yet on peer
        self.test_receive_advertisement(address=nearby_device.address,
                                        timeout=30)

        # Pair the nearby device first - necessary for later connection to
        # secondary device
        self.pair_adapter_to_device(nearby_device)

        # Register and start non-connectable advertising instance
        # We ignore failure because the test isn't able to verify the min/max
        # advertising intervals, but this is ok.
        self.test_reset_advertising()
        self.test_set_advertising_intervals(DEFAULT_MIN_ADV_INTERVAL,
                                            DEFAULT_MAX_ADV_INTERVAL)
        self.test_register_advertisement(advertisements_data.ADVERTISEMENTS[0],
                                         1, DEFAULT_MIN_ADV_INTERVAL,
                                         DEFAULT_MAX_ADV_INTERVAL)

        # If test requires it, connect and test secondary device
        if secondary_info is not None and device_use == 'mid':
            self.connect_and_test_secondary_device(
                secondary_device_handle, secondary_test_func)

        # Discover DUT from peer
        self.test_discover_by_device(nearby_device)

        # Connect to DUT from peer
        self.test_connection_by_device(nearby_device)

        # TODO(b/164131633) On 4.4 kernel, sometimes the input device is not
        # created if we connect a second device too quickly
        time.sleep(self.TEST_SLEEP_SECS)

        # If test requires it, connect and test secondary device
        if secondary_info is not None and device_use == 'end':
            self.connect_and_test_secondary_device(
                secondary_device_handle, secondary_test_func)

        time.sleep(self.TEST_SLEEP_SECS)

        # Try data test with nearby device
        nearby_device_test_func(nearby_device)

        self.test_disconnection_by_device(nearby_device)
        self.test_reset_advertising()
