#/usr/bin/env python3.4
#
# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""
This test script exercises different scan filters with different screen states.
"""

import concurrent
import json
import pprint
import time

from queue import Empty
from acts.test_decorators import test_tracker_info
from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
from acts.test_utils.bt.bt_constants import adv_succ
from acts.test_utils.bt.bt_constants import ble_advertise_settings_modes
from acts.test_utils.bt.bt_constants import ble_scan_settings_modes
from acts.test_utils.bt.bt_constants import bt_default_timeout
from acts.test_utils.bt.bt_constants import scan_result
from acts.test_utils.bt.bt_test_utils import batch_scan_result
from acts.test_utils.bt.bt_test_utils import generate_ble_advertise_objects
from acts.test_utils.bt.bt_test_utils import generate_ble_scan_objects
from acts.test_utils.bt.bt_test_utils import reset_bluetooth


class BleScanScreenStateTest(BluetoothBaseTest):
    advertise_callback = -1
    max_concurrent_scans = 28
    scan_callback = -1
    shorter_scan_timeout = 2

    def __init__(self, controllers):
        BluetoothBaseTest.__init__(self, controllers)
        self.scn_ad = self.android_devices[0]
        self.adv_ad = self.android_devices[1]

    def _setup_generic_advertisement(self):
        self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
            ble_advertise_settings_modes['low_latency'])
        self.advertise_callback, advertise_data, advertise_settings = (
            generate_ble_advertise_objects(self.adv_ad.droid))
        self.adv_ad.droid.bleStartBleAdvertising(
            self.advertise_callback, advertise_data, advertise_settings)
        try:
            self.adv_ad.ed.pop_event(adv_succ.format(self.advertise_callback))
        except Empty:
            self.log.error("Failed to start advertisement.")
            return False
        return True

    def _setup_scan_with_no_filters(self):
        filter_list, scan_settings, self.scan_callback = \
            generate_ble_scan_objects(self.scn_ad.droid)
        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          self.scan_callback)

    def _scan_found_results(self):
        try:
            self.scn_ad.ed.pop_event(
                scan_result.format(self.scan_callback), bt_default_timeout)
            self.log.info("Found an advertisement.")
        except Empty:
            self.log.info("Did not find an advertisement.")
            return False
        return True

    @BluetoothBaseTest.bt_test_wrap
    @test_tracker_info(uuid='9b695819-e5a8-48b3-87a0-f90422998bf9')
    def test_scan_no_filters_screen_on(self):
        """Test LE scanning is successful with no filters and screen on.

        Test LE scanning is successful with no filters and screen on. Scan
        results should be found.

        Steps:
        1. Setup advertisement
        2. Turn on screen
        3. Start scanner without filters
        4. Verify scan results are found
        5. Teardown advertisement and scanner

        Expected Result:
        Scan results should be found.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Filtering, Scanning, Screen
        Priority: 2
        """
        # Step 1
        if not self._setup_generic_advertisement():
            return False

        # Step 2
        self.scn_ad.droid.wakeUpNow()

        # Step 3
        self._setup_scan_with_no_filters()

        # Step 4
        if not self._scan_found_results():
            return False

        # Step 5
        self.adv_ad.droid.bleStopBleAdvertising(self.advertise_callback)
        self.scn_ad.droid.bleStopBleScan(self.scan_callback)
        return True

    @BluetoothBaseTest.bt_test_wrap
    @test_tracker_info(uuid='38fb6959-f07b-4501-814b-81a498e3efc4')
    def test_scan_no_filters_screen_off(self):
        """Test LE scanning is successful with no filters and screen off.

        Test LE scanning is successful with no filters and screen off. No scan
        results should be found.

        Steps:
        1. Setup advertisement
        2. Turn off screen
        3. Start scanner without filters
        4. Verify no scan results are found
        5. Teardown advertisement and scanner

        Expected Result:
        No scan results should be found.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Filtering, Scanning, Screen
        Priority: 1
        """
        # Step 1
        if not self._setup_generic_advertisement():
            return False

        # Step 2
        self.scn_ad.droid.goToSleepNow()
        # Give the device time to go to sleep
        time.sleep(2)

        # Step 3
        self._setup_scan_with_no_filters()

        # Step 4
        if self._scan_found_results():
            return False

        # Step 5
        self.adv_ad.droid.bleStopBleAdvertising(self.advertise_callback)
        self.scn_ad.droid.bleStopBleScan(self.scan_callback)
        return True

    @BluetoothBaseTest.bt_test_wrap
    @test_tracker_info(uuid='7186ef2f-096a-462e-afde-b0e3d4ecdd83')
    def test_scan_filters_works_with_screen_off(self):
        """Test LE scanning is successful with filters and screen off.

        Test LE scanning is successful with no filters and screen off. No scan
        results should be found.

        Steps:
        1. Setup advertisement
        2. Turn off screen
        3. Start scanner with filters
        4. Verify scan results are found
        5. Teardown advertisement and scanner

        Expected Result:
        Scan results should be found.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Filtering, Scanning, Screen
        Priority: 1
        """
        # Step 1
        adv_device_name = self.adv_ad.droid.bluetoothGetLocalName()
        print(adv_device_name)
        self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
        if not self._setup_generic_advertisement():
            return False

        # Step 2
        self.scn_ad.droid.goToSleepNow()

        # Step 3
        self.scn_ad.droid.bleSetScanFilterDeviceName(adv_device_name)
        filter_list, scan_settings, self.scan_callback = generate_ble_scan_objects(
            self.scn_ad.droid)
        self.scn_ad.droid.bleBuildScanFilter(filter_list)
        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          self.scan_callback)

        # Step 4
        if not self._scan_found_results():
            return False

        # Step 5
        self.adv_ad.droid.bleStopBleAdvertising(self.advertise_callback)
        self.scn_ad.droid.bleStopBleScan(self.scan_callback)
        return True

    @BluetoothBaseTest.bt_test_wrap
    @test_tracker_info(uuid='02cd6dca-149e-439b-8427-a2edc7864265')
    def test_scan_no_filters_screen_off_then_turn_on(self):
        """Test start LE scan with no filters while screen is off then turn on.

        Test that a scan without filters will not return results while the
        screen is off but will return results when the screen turns on.

        Steps:
        1. Setup advertisement
        2. Turn off screen
        3. Start scanner without filters
        4. Verify no scan results are found
        5. Turn screen on
        6. Verify scan results are found
        7. Teardown advertisement and scanner

        Expected Result:
        Scan results should only come in when the screen is on.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Filtering, Scanning, Screen
        Priority: 2
        """
        # Step 1
        if not self._setup_generic_advertisement():
            return False

        # Step 2
        self.scn_ad.droid.goToSleepNow()
        # Give the device time to go to sleep
        time.sleep(2)

        # Step 3
        self._setup_scan_with_no_filters()

        # Step 4
        if self._scan_found_results():
            return False

        # Step 5
        self.scn_ad.droid.wakeUpNow()

        # Step 6
        if not self._scan_found_results():
            return False

        # Step 7
        self.adv_ad.droid.bleStopBleAdvertising(self.advertise_callback)
        self.scn_ad.droid.bleStopBleScan(self.scan_callback)
        return True

    @BluetoothBaseTest.bt_test_wrap
    @test_tracker_info(uuid='eb9fc373-f5e8-4a55-9750-02b7a11893d1')
    def test_scan_no_filters_screen_on_then_turn_off(self):
        """Test start LE scan with no filters while screen is on then turn off.

        Test that a scan without filters will not return results while the
        screen is off but will return results when the screen turns on.

        Steps:
        1. Setup advertisement
        2. Turn off screen
        3. Start scanner without filters
        4. Verify no scan results are found
        5. Turn screen on
        6. Verify scan results are found
        7. Teardown advertisement and scanner

        Expected Result:
        Scan results should only come in when the screen is on.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Filtering, Scanning, Screen
        Priority: 2
        """
        # Step 1
        if not self._setup_generic_advertisement():
            return False

        # Step 2
        self.scn_ad.droid.wakeUpNow()

        # Step 3
        self._setup_scan_with_no_filters()

        # Step 4
        if not self._scan_found_results():
            return False

        # Step 5
        self.scn_ad.droid.goToSleepNow()
        # Give the device time to go to sleep
        time.sleep(2)
        self.scn_ad.ed.clear_all_events()

        # Step 6
        if self._scan_found_results():
            return False

        # Step 7
        self.adv_ad.droid.bleStopBleAdvertising(self.advertise_callback)
        self.scn_ad.droid.bleStopBleScan(self.scan_callback)
        return True

    @BluetoothBaseTest.bt_test_wrap
    @test_tracker_info(uuid='41d90e11-b0a8-4eed-bff1-c19678920762')
    def test_scan_no_filters_screen_toggling(self):
        """Test start LE scan with no filters and test screen toggling.

        Test that a scan without filters will not return results while the
        screen is off and return results while the screen is on.

        Steps:
        1. Setup advertisement
        2. Turn off screen
        3. Start scanner without filters
        4. Verify no scan results are found
        5. Turn screen on
        6. Verify scan results are found
        7. Repeat steps 1-6 10 times
        7. Teardown advertisement and scanner

        Expected Result:
        Scan results should only come in when the screen is on.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Filtering, Scanning, Screen
        Priority: 3
        """
        iterations = 10
        # Step 1
        if not self._setup_generic_advertisement():
            return False

        for i in range(iterations):
            self.log.info("Starting iteration {}".format(i + 1))
            # Step 2
            self.scn_ad.droid.goToSleepNow()
            # Give the device time to go to sleep
            time.sleep(2)
            self.scn_ad.ed.clear_all_events()

            # Step 3
            self._setup_scan_with_no_filters()

            # Step 4
            if self._scan_found_results():
                return False

            # Step 5
            self.scn_ad.droid.wakeUpNow()

            # Step 6
            if not self._scan_found_results():
                return False

        # Step 7
        self.adv_ad.droid.bleStopBleAdvertising(self.advertise_callback)
        self.scn_ad.droid.bleStopBleScan(self.scan_callback)
        return True

    @BluetoothBaseTest.bt_test_wrap
    @test_tracker_info(uuid='7a2fe7ef-b15f-4e93-a2f0-40e2f7d9cbcb')
    def test_opportunistic_scan_no_filters_screen_off_then_on(self):
        """Test opportunistic scanning does not find results with screen off.

        Test LE scanning is successful with no filters and screen off. No scan
        results should be found.

        Steps:
        1. Setup advertisement
        2. Turn off screen
        3. Start opportunistic scan without filters
        4. Start scan without filters
        5. Verify no scan results are found on either scan instance
        6. Wake up phone
        7. Verify scan results on each scan instance
        8. Teardown advertisement and scanner

        Expected Result:
        No scan results should be found.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Filtering, Scanning, Screen
        Priority: 1
        """
        # Step 1
        if not self._setup_generic_advertisement():
            return False

        # Step 2
        self.scn_ad.droid.goToSleepNow()
        # Give the device time to go to sleep
        time.sleep(2)

        # Step 3
        self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[
            'opportunistic'])
        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
            self.scn_ad.droid)
        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          scan_callback)

        # Step 4
        filter_list2, scan_settings2, scan_callback2 = generate_ble_scan_objects(
            self.scn_ad.droid)
        self.scn_ad.droid.bleStartBleScan(filter_list2, scan_settings2,
                                          scan_callback2)

        # Step 5
        try:
            self.scn_ad.ed.pop_event(
                scan_result.format(scan_callback), self.shorter_scan_timeout)
            self.log.error("Found an advertisement on opportunistic scan.")
            return False
        except Empty:
            self.log.info("Did not find an advertisement.")
        try:
            self.scn_ad.ed.pop_event(
                scan_result.format(scan_callback2), self.shorter_scan_timeout)
            self.log.error("Found an advertisement on scan instance.")
            return False
        except Empty:
            self.log.info("Did not find an advertisement.")

        # Step 6
        self.scn_ad.droid.wakeUpNow()

        # Step 7
        try:
            self.scn_ad.ed.pop_event(
                scan_result.format(scan_callback), self.shorter_scan_timeout)
            self.log.info("Found an advertisement on opportunistic scan.")
        except Empty:
            self.log.error(
                "Did not find an advertisement on opportunistic scan.")
            return False
        try:
            self.scn_ad.ed.pop_event(
                scan_result.format(scan_callback2), self.shorter_scan_timeout)
            self.log.info("Found an advertisement on scan instance.")
        except Empty:
            self.log.info("Did not find an advertisement.")
            return False

        # Step 8
        self.adv_ad.droid.bleStopBleAdvertising(self.advertise_callback)
        self.scn_ad.droid.bleStopBleScan(scan_callback)
        self.scn_ad.droid.bleStopBleScan(scan_callback2)
        return True

    @BluetoothBaseTest.bt_test_wrap
    @test_tracker_info(uuid='406f1a2e-160f-4fb2-8a87-6403996df36e')
    def test_max_scan_no_filters_screen_off_then_turn_on(self):
        """Test start max scans with no filters while screen is off then turn on

        Test that max LE scan without filters will not return results while the
        screen is off but will return results when the screen turns on.

        Steps:
        1. Setup advertisement
        2. Turn off screen
        3. Start scanner without filters and verify no scan results
        4. Turn screen on
        5. Verify scan results are found on each scan callback
        6. Teardown advertisement and all scanner

        Expected Result:
        Scan results should only come in when the screen is on.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Filtering, Scanning, Screen
        Priority: 2
        """
        # Step 1
        if not self._setup_generic_advertisement():
            return False

        # Step 2
        self.scn_ad.droid.goToSleepNow()
        # Give the device time to go to sleep
        time.sleep(2)

        # Step 3
        scan_callback_list = []
        for _ in range(self.max_concurrent_scans):
            filter_list, scan_settings, scan_callback = \
                generate_ble_scan_objects(self.scn_ad.droid)
            self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                              scan_callback)
            scan_callback_list.append(scan_callback)
            try:
                self.scn_ad.ed.pop_event(
                    scan_result.format(self.scan_callback),
                    self.shorter_scan_timeout)
                self.log.info("Found an advertisement.")
                return False
            except Empty:
                self.log.info("Did not find an advertisement.")

        # Step 4
        self.scn_ad.droid.wakeUpNow()

        # Step 5
        for callback in scan_callback_list:
            try:
                self.scn_ad.ed.pop_event(
                    scan_result.format(callback), self.shorter_scan_timeout)
                self.log.info("Found an advertisement.")
            except Empty:
                self.log.info("Did not find an advertisement.")
                return False

        # Step 7
        self.adv_ad.droid.bleStopBleAdvertising(self.advertise_callback)
        for callback in scan_callback_list:
            self.scn_ad.droid.bleStopBleScan(callback)
        return True
