#!/usr/bin/env python3.4
#
#   Copyright 2016 - 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.

import itertools
import queue

from acts import asserts
from acts import base_test
from acts import utils
from acts.test_decorators import test_tracker_info
from acts.test_utils.wifi import wifi_test_utils as wutils

BSSID_EVENT_WAIT = 30

BSSID_EVENT_TAG = "WifiScannerBssid"
SCAN_EVENT_TAG = "WifiScannerScan"
SCANTIME = 10000  #framework support only 10s as minimum scan interval


class WifiScannerBssidError(Exception):
    pass


class WifiScannerBssidTest(base_test.BaseTestClass):
    def __init__(self, controllers):
        base_test.BaseTestClass.__init__(self, controllers)
        # A list of all test cases to be executed in this class.
        self.tests = ("test_wifi_track_bssid_sanity",
                      "test_wifi_track_bssid_found",
                      "test_wifi_track_bssid_lost",
                      "test_wifi_track_bssid_for_2g_while_scanning_5g_channels",
                      "test_wifi_track_bssid_for_5g_while_scanning_2g_channels",)

    def setup_class(self):
        self.default_scan_setting = {
            "band": wutils.WifiEnums.WIFI_BAND_BOTH_WITH_DFS,
            "periodInMs": SCANTIME,
            "reportEvents": wutils.WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN,
            'numBssidsPerScan': 32
        }
        self.leeway = 5
        self.stime_channel = 47  #dwell time plus 2ms
        self.dut = self.android_devices[0]
        wutils.wifi_test_device_init(self.dut)
        self.attenuators = wutils.group_attenuators(self.attenuators)
        asserts.assert_true(self.dut.droid.wifiIsScannerSupported(),
                            "Device %s doesn't support WifiScanner, abort." %
                            self.dut.model)
        """It will setup the required dependencies and fetch the user params from
          config file"""
        self.attenuators[0].set_atten(0)
        self.attenuators[1].set_atten(0)
        req_params = ("bssid_2g", "bssid_5g", "bssid_dfs", "attenuator_id",
                      "max_bugreports")
        self.wifi_chs = wutils.WifiChannelUS(self.dut.model)
        self.unpack_userparams(req_params, two_ap_testbed=False)

    def teardown_class(self):
        BaseTestClass.teardown_test(self)
        self.log.debug("Shut down all wifi scanner activities.")
        self.dut.droid.wifiScannerShutdown()

    def on_fail(self, test_name, begin_time):
        if self.max_bugreports > 0:
            self.dut.take_bug_report(test_name, begin_time)
            self.max_bugreports -= 1

    """ Helper Functions Begin """

    def fetch_scan_result(self, scan_idx, scan_setting):
        """Fetch the scan result for provider listener index.

        This function calculate the time required for scanning based on scan setting
        and wait for scan result event, on triggering of event process the scan result.

        Args:
          scan_idx: Index of the scan listener.
          scan_setting: Setting used for starting the scan.

        Returns:
          scan_results: if scan result available.
        """
        #generating event wait time from scan setting plus leeway
        self.log.debug(scan_setting)
        scan_time, scan_channels = wutils.get_scan_time_and_channels(
            self.wifi_chs, scan_setting, self.stime_channel)
        scan_time += scan_setting['periodInMs'
                                  ]  #add scan period delay for next cycle
        if scan_setting[
                "reportEvents"] == wutils.WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN:
            waittime = int(scan_time / 1000) + self.leeway
        else:
            time_cache = scan_setting['periodInMs'] * 10  #default cache
            waittime = int((time_cache + scan_time) / 1000) + self.leeway
        event_name = "%s%sonResults" % (SCAN_EVENT_TAG, scan_idx)
        self.log.info("Waiting for the scan result event %s", event_name)
        event = self.dut.ed.pop_event(event_name, waittime)
        results = event["data"]["Results"]
        if len(results) > 0 and "ScanResults" in results[0]:
            return results[0]["ScanResults"]

    def start_scan_and_validate_environment(self, scan_setting,
                                            bssid_settings):
        """Validate environment for test using current scan result for provided
           settings.

        This function start the scan for given setting and verify that interested
        Bssids are in scan result or not.

        Args:
            scan_setting: Setting used for starting the scan.
            bssid_settings: list of bssid settings.

        Returns:
            True, if bssid not found in scan result.
        """
        try:
            data = wutils.start_wifi_background_scan(self.dut, scan_setting)
            self.scan_idx = data["Index"]
            results = self.fetch_scan_result(self.scan_idx, scan_setting)
            self.log.debug("scan result %s.", results)
            asserts.assert_true(results,
                                "Device is not able to fetch the scan results")
            for result in results:
                for bssid_setting in bssid_settings:
                    if bssid_setting[wutils.WifiEnums.BSSID_KEY] == result[
                            wutils.WifiEnums.BSSID_KEY]:
                        asserts.fail(("Test environment is not valid: Bssid %s"
                                      "already exist in current scan results")
                                     % result[wutils.WifiEnums.BSSID_KEY])
        except queue.Empty as error:
            self.dut.droid.wifiScannerStopBackgroundScan(self.scan_idx)
            raise AssertionError(
                "OnResult event did not triggered for scanner\n%s" % error)

    def check_bssid_in_found_result(self, bssid_settings, found_results):
        """look for any tracked bssid in reported result of found bssids.

        Args:
            bssid_settings:Setting used for tracking bssids.
            found_results: Result reported in found event.

        Returns:
            True if bssid is present in result.
        """
        for bssid_setting in bssid_settings:
            for found_result in found_results:
                if found_result[wutils.WifiEnums.BSSID_KEY] == bssid_setting[
                        wutils.WifiEnums.BSSID_KEY]:
                    return
        asserts.fail("Test fail because Bssid %s is not found in event results"
                     % bssid_settings)

    def track_bssid_with_vaild_scan_for_found(self, track_setting):
        """Common logic for tracking a bssid for Found event.

         1. Starts Wifi Scanner bssid tracking for interested bssids in track_setting.
         2. Start Wifi Scanner scan with default scan settings.
         3. Validate the environment to check AP is not in range.
         4. Attenuate the signal to make AP in range.
         5. Verified that onFound event is triggered for interested bssids in
            track setting.

        Args:
            track_setting: Setting for bssid tracking.

        Returns:
            True if found event occur for interested BSSID.
        """
        self.attenuators[self.attenuator_id].set_atten(90)
        data = wutils.start_wifi_track_bssid(self.dut, track_setting)
        idx = data["Index"]
        self.start_scan_and_validate_environment(self.default_scan_setting,
                                                 track_setting["bssidInfos"])
        try:
            self.attenuators[self.attenuator_id].set_atten(0)
            event_name = "%s%sonFound" % (BSSID_EVENT_TAG, idx)
            self.log.info("Waiting for the BSSID event %s", event_name)
            event = self.dut.ed.pop_event(event_name, BSSID_EVENT_WAIT)
            self.log.debug(event)
            self.check_bssid_in_found_result(track_setting["bssidInfos"],
                                             event["data"]["Results"])
        except queue.Empty as error:
            self.log.error(error)
            # log scan result for debugging
            results = self.fetch_scan_result(self.scan_idx,
                                             self.default_scan_setting)
            self.log.debug("scan result %s", results)
            raise AssertionError("Event %s did not triggered for %s\n%s" %
                                 (event_name, track_setting["bssidInfos"],
                                  error))
        finally:
            self.dut.droid.wifiScannerStopBackgroundScan(self.scan_idx)
            self.dut.droid.wifiScannerStopTrackingBssids(idx)

    def track_bssid_with_vaild_scan_for_lost(self, track_setting):
        """Common logic for tracking a bssid for Lost event.

         1. Start Wifi Scanner scan with default scan settings.
         2. Validate the environment to check AP is not in range.
         3. Starts Wifi Scanner bssid tracking for interested bssids in track_setting.
         4. Attenuate the signal to make Bssids in range.
         5. Verified that onFound event is triggered for interested bssids in
            track setting.
         6. Attenuate the signal to make Bssids out of range.
         7. Verified that onLost event is triggered.

        Args:
            track_setting: Setting for bssid tracking.
            scan_setting: Setting used for starting the scan.

        Returns:
            True if Lost event occur for interested BSSID.
        """
        self.attenuators[self.attenuator_id].set_atten(90)
        self.start_scan_and_validate_environment(self.default_scan_setting,
                                                 track_setting["bssidInfos"])
        idx = None
        found = False
        try:
            data = wutils.start_wifi_track_bssid(self.dut, track_setting)
            idx = data["Index"]
            self.attenuators[self.attenuator_id].set_atten(0)
            #onFound event should be occurre before tracking for onLost event
            event_name = "%s%sonFound" % (BSSID_EVENT_TAG, idx)
            self.log.info("Waiting for the BSSID event %s", event_name)
            event = self.dut.ed.pop_event(event_name, BSSID_EVENT_WAIT)
            self.log.debug(event)
            self.check_bssid_in_found_result(track_setting["bssidInfos"],
                                             event["data"]["Results"])
            self.attenuators[self.attenuator_id].set_atten(90)
            # log scan result for debugging
            for i in range(1, track_setting["apLostThreshold"]):
                results = self.fetch_scan_result(self.scan_idx,
                                                 self.default_scan_setting)
                self.log.debug("scan result %s %s", i, results)
            event_name = "%s%sonLost" % (BSSID_EVENT_TAG, idx)
            self.log.info("Waiting for the BSSID event %s", event_name)
            event = self.dut.ed.pop_event(event_name, BSSID_EVENT_WAIT)
            self.log.debug(event)
        except queue.Empty as error:
            raise AssertionError("Event %s did not triggered for %s\n%s" %
                                 (event_name, track_setting["bssidInfos"],
                                  error))
        finally:
            self.dut.droid.wifiScannerStopBackgroundScan(self.scan_idx)
            if idx:
                self.dut.droid.wifiScannerStopTrackingBssids(idx)

    def wifi_generate_track_bssid_settings(self, isLost):
        """Generates all the combinations of different track setting parameters.

        Returns:
            A list of dictionaries each representing a set of track settings.
        """
        bssids = [[self.bssid_2g], [self.bssid_5g],
                  [self.bssid_2g, self.bssid_5g]]
        if self.dut.model != "hammerhead" or not self.two_ap_testbed:
            bssids.append([self.bssid_dfs])
        if isLost:
            apthreshold = (3, 5)
        else:
            apthreshold = (1, )
        # Create track setting strings based on the combinations
        setting_combinations = list(itertools.product(bssids, apthreshold))
        # Create scan setting strings based on the combinations
        track_settings = []
        for combo in setting_combinations:
            s = {}
            s["bssidInfos"] = combo[0]
            s["apLostThreshold"] = combo[1]
            track_settings.append(s)
        return track_settings

    def track_setting_to_string(self, track_setting):
        """Convert track setting to string for Bssids in that"""
        string = ""
        for bssid_setting in track_setting:
            string += bssid_setting[wutils.WifiEnums.BSSID_KEY]
            string += "_"
        return string

    def combineBssids(self, *track_settings):
        """Combine bssids in the track_settings to one list"""
        bssids = []
        for track_setting in track_settings:
            bssids.extend(track_setting["bssidInfos"])
        return bssids

    """ Helper Functions End """
    """ Tests Begin """

    @test_tracker_info(uuid="599a30b8-73ad-4314-a245-7ec58fc7e74b")
    def test_wifi_track_bssid_found(self):
        """Test bssid track for event found with a list of different settings.

         1. Starts Wifi Scanner bssid tracking for interested bssids in track_setting.
         2. Start Wifi Scanner scan with default scan settings.
         3. Validate the environment to check AP is not in range.
         4. Attenuate the signal to make AP in range.
         5. Verified that onFound event is triggered for interested bssids in
            track setting.
        """
        track_settings = self.wifi_generate_track_bssid_settings(False)
        name_func = lambda track_setting: "test_wifi_track_found_bssidInfos_%sapLostThreshold_%s" % (self.track_setting_to_string(track_setting["bssidInfos"]), track_setting["apLostThreshold"])
        failed = self.run_generated_testcases(
            self.track_bssid_with_vaild_scan_for_found,
            track_settings,
            name_func=name_func)
        asserts.assert_false(
            failed, "Track bssid found failed with these bssids: %s" % failed)

    @test_tracker_info(uuid="7ebd4b61-c408-45b3-b9b6-098753d46aa7")
    def test_wifi_track_bssid_lost(self):
        """Test bssid track for event lost with a list of different settings.

         1. Start Wifi Scanner scan with default scan settings.
         2. Validate the environment to check AP is not in range.
         3. Starts Wifi Scanner bssid tracking for interested bssids in track_setting.
         4. Attenuate the signal to make Bssids in range.
         5. Verified that onFound event is triggered for interested bssids in
            track setting.
         6. Attenuate the signal to make Bssids out of range.
         7. Verified that onLost event is triggered.
        """
        track_settings = self.wifi_generate_track_bssid_settings(True)
        name_func = lambda track_setting: "test_wifi_track_lost_bssidInfos_%sapLostThreshold_%s" % (self.track_setting_to_string(track_setting["bssidInfos"]), track_setting["apLostThreshold"])
        failed = self.run_generated_testcases(
            self.track_bssid_with_vaild_scan_for_lost,
            track_settings,
            name_func=name_func)
        asserts.assert_false(
            failed, "Track bssid lost failed with these bssids: %s" % failed)

    def test_wifi_track_bssid_sanity(self):
        """Test bssid track for event found and lost with default settings.

         1. Start WifiScanner scan for default scan settings.
         2. Start Bssid track for "bssid_2g" AP.
         3. Attenuate the signal to move in AP range.
         4. Verify that onFound event occur.
         5. Attenuate the signal to move out of range
         6. Verify that onLost event occur.
        """
        track_setting = {"bssidInfos": [self.bssid_2g], "apLostThreshold": 3}
        self.track_bssid_with_vaild_scan_for_lost(track_setting)

    def test_wifi_track_bssid_for_2g_while_scanning_5g_channels(self):
        """Test bssid track for 2g bssids while scanning 5g channels.

         1. Starts Wifi Scanner bssid tracking for 2g bssids in track_setting.
         2. Start Wifi Scanner scan for 5G Band only.
         3. Validate the environment to check AP is not in range.
         4. Attenuate the signal to make AP in range.
         5. Verified that onFound event isn't triggered for 2g bssids.
      """
        self.attenuators[self.attenuator_id].set_atten(90)
        scan_setting = {"band": wutils.WifiEnums.WIFI_BAND_5_GHZ,
                        "periodInMs": SCANTIME,
                        "reportEvents":
                        wutils.WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN,
                        "numBssidsPerScan": 32}
        track_setting = {"bssidInfos": [self.bssid_2g], "apLostThreshold": 3}
        self.start_scan_and_validate_environment(scan_setting,
                                                 track_setting["bssidInfos"])
        idx = None
        try:
            data = wutils.start_wifi_track_bssid(self.dut, track_setting)
            idx = data["Index"]
            self.attenuators[self.attenuator_id].set_atten(0)
            event_name = "%s%sonFound" % (BSSID_EVENT_TAG, idx)
            self.log.info("Waiting for the BSSID event %s", event_name)
            #waiting for 2x time to make sure
            event = self.dut.ed.pop_event(event_name, BSSID_EVENT_WAIT * 2)
            self.log.debug(event)
            self.check_bssid_in_found_result(track_setting["bssidInfos"],
                                             event["data"]["Results"])
        except queue.Empty as error:
            self.log.info(
                "As excepted event didn't occurred with different scan setting")
        finally:
            self.dut.droid.wifiScannerStopBackgroundScan(self.scan_idx)
            if idx:
                self.dut.droid.wifiScannerStopTrackingBssids(idx)

    def test_wifi_track_bssid_for_5g_while_scanning_2g_channels(self):
        """Test bssid track for 5g bssids while scanning 2g channels.

           1. Starts Wifi Scanner bssid tracking for 5g bssids in track_setting.
           2. Start Wifi Scanner scan for 2G Band only.
           3. Validate the environment to check AP is not in range.
           4. Attenuate the signal to make AP in range.
           5. Verified that onFound event isn't triggered for 5g bssids.
        """
        self.attenuators[self.attenuator_id].set_atten(90)
        scan_setting = {"band": wutils.WifiEnums.WIFI_BAND_24_GHZ,
                        "periodInMs": SCANTIME,
                        "reportEvents":
                        wutils.WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN,
                        "numBssidsPerScan": 32}
        track_setting = {"bssidInfos": [self.bssid_5g], "apLostThreshold": 3}
        data = wutils.start_wifi_track_bssid(self.dut, track_setting)
        idx = data["Index"]
        self.start_scan_and_validate_environment(scan_setting,
                                                 track_setting["bssidInfos"])
        try:
            self.attenuators[self.attenuator_id].set_atten(0)
            event_name = "%s%sonFound" % (BSSID_EVENT_TAG, idx)
            self.log.info("Waiting for the BSSID event %s", event_name)
            #waiting for 2x time to make sure
            event = self.dut.ed.pop_event(event_name, BSSID_EVENT_WAIT * 2)
            self.log.debug(event)
            self.check_bssid_in_found_result(track_setting["bssidInfos"],
                                             event["data"]["Results"])
        except queue.Empty as error:
            self.log.info(
                "As excepted event didn't occurred with different scan setting")
        finally:
            self.dut.droid.wifiScannerStopBackgroundScan(self.scan_idx)
            if idx:
                self.dut.droid.wifiScannerStopTrackingBssids(idx)

    def test_wifi_tracking_bssid_multi_listeners_found(self):
        """Test bssid tracking for multiple listeners
            1. Start BSSID tracking for 5g bssids
            2. Start BSSID tracking for 2g bssids
            3. Start WifiScanner scan on both bands.
            4. Valid the environment and check the APs are not in range.
            5. Attenuate the signal to make the APs in range.
            6. Verify onFound event triggered on both APs.
        """
        # Attenuate the signal to make APs invisible.
        self.attenuators[self.attenuator_id].set_atten(90)
        scan_setting = { "band": WifiEnums.WIFI_BAND_BOTH_WITH_DFS,
                         "periodInMs": SCANTIME,
                         "reportEvents": WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN,
                         "numBssidsPerScan": 32}
        track_setting_5g = {"bssidInfos":[self.bssid_5g], "apLostThreshold":3}
        data_5g = start_wifi_track_bssid(self.dut, track_setting_5g)
        idx_5g = data_5g["Index"]

        track_setting_2g = {"bssidInfos":[self.bssid_2g], "apLostThreshold":3}
        data_2g = start_wifi_track_bssid(self.dut, track_setting_2g)
        idx_2g = data_2g["Index"]

        valid_env = self.start_scan_and_validate_environment(
            scan_setting, self.combineBssids(track_setting_5g, track_setting_2g))
        try:
            asserts.assert_true(valid_env,
                                "Test environment is not valid, AP is in range")
            self.attenuators[self.attenuator_id].set_atten(0)
            event_name = "{}{}{}{}onFound".format(BSSID_EVENT_TAG, idx_5g, BSSID_EVENT_TAG, idx_2g)
            self.log.info("Waiting for the BSSID event {}".format(event_name))
            #waiting for 2x time to make sure
            event = self.dut.ed.pop_event(event_name, BSSID_EVENT_WAIT * 2)
            self.log.debug(event)
            found = self.check_bssid_in_found_result(
                self.combineBssids(track_setting_5g, track_setting_2g),
                event["data"]["Results"])
            asserts.assert_true(found,
                                "Test failed because Bssid onFound event is not triggered")
        finally:
            self.dut.droid.wifiScannerStopBackgroundScan(self.scan_idx)
            if idx_5g:
                self.dut.droid.wifiScannerStopTrackingBssids(idx_5g)
            if idx_2g:
                self.dut.droid.wifiScannerStopTrackingBssids(idx_2g);

""" Tests End """
