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

import logging
import math
import os
import time

from acts import base_test
from acts import utils
from acts.controllers.ap_lib import hostapd_constants as hc
from acts.test_decorators import test_tracker_info
from acts.test_utils.bt import bt_power_test_utils as btutils
from acts.test_utils.bt.bt_constants import ble_scan_settings_modes
from acts.test_utils.wifi import wifi_power_test_utils as wputils


class PowerCoexScanTest(base_test.BaseTestClass):
    def __init__(self, controllers):

        base_test.BaseTestClass.__init__(self, controllers)

    def setup_class(self):

        self.log = logging.getLogger()
        self.dut = self.android_devices[0]
        self.access_point = self.access_points[0]
        req_params = ['coexscan_params', 'custom_files']
        self.unpack_userparams(req_params)
        self.unpack_testparams(self.coexscan_params)
        self.mon_data_path = os.path.join(self.log_path, 'Monsoon')
        self.mon = self.monsoons[0]
        self.mon.set_max_current(wputils.MONSOON_MAX_CURRENT)
        self.mon.set_voltage(wputils.PHONE_BATTERY_VOLTAGE)
        self.mon.attach_device(self.dut)
        self.mon_info = wputils.create_monsoon_info(self)
        self.num_atten = self.attenuators[0].instrument.num_atten
        for file in self.custom_files:
            if 'pass_fail_threshold' in file:
                self.threshold_file = file
            elif 'attenuator_setting' in file:
                self.attenuation_file = file
            elif 'network_config' in file:
                self.network_file = file
        self.threshold = wputils.unpack_custom_file(self.threshold_file,
                                                    self.TAG)
        self.atten_level = wputils.unpack_custom_file(self.attenuation_file,
                                                      self.TAG)
        self.networks = wputils.unpack_custom_file(self.network_file)
        self.main_network = self.networks['main_network']

        # Start PMC app.
        self.log.info('Start PMC app...')
        self.dut.adb.shell(btutils.START_PMC_CMD)
        self.dut.adb.shell(btutils.PMC_VERBOSE_CMD)

    def setup_test(self):

        iterations = math.floor((self.mon_duration + self.mon_offset + 10) /
                                self.wifi_scan_interval)

        self.PERIODIC_WIFI_SCAN = (
            'am instrument -w -r -e scan-interval \"%d\" -e scan-iterations'
            ' \"%d\" -e class com.google.android.platform.powertests.'
            'WifiTests#testGScanAllChannels com.google.android.platform.'
            'powertests/android.test.InstrumentationTestRunner > /dev/null &' %
            (self.wifi_scan_interval, iterations))

    def teardown_class(self):
        """Clean up the test class after all tests finish running

        """
        self.mon.usb('on')
        self.access_point.close()  # Just as a precaution

    def teardown_test(self):
        """Tear down necessary objects/settings after test finishes

        """
        self.dut.adb.shell(btutils.BLE_LOCATION_SCAN_DISABLE)
        if self.brconfigs:
            self.access_point.bridge.teardown(self.brconfigs)
        self.access_point.close()

    def unpack_testparams(self, bulk_params):
        """Unpack all the test specific parameters

        Args:
            bulk_params: dict with all test specific params in the config file
        """
        for key in bulk_params.keys():
            setattr(self, key, bulk_params[key])

    def measure_power(self):
        """Measures current consumption and evaluates pass/fail criteria

        """
        # Measure current and plot
        begin_time = utils.get_current_epoch_time()
        file_path, avg_current = wputils.monsoon_data_collect_save(
            self.dut, self.mon_info, self.current_test_name)
        wputils.monsoon_data_plot(self.mon_info, file_path)

        # Take Bugreport
        if bool(self.bug_report) == True:
            self.dut.take_bug_report(self.test_name, begin_time)

        # Compute pass or fail check
        wputils.pass_fail_check(self, avg_current)

    @test_tracker_info(uuid='a998dd2b-f5f1-4361-b5da-83e42a69e80b')
    def test_ble_scan_balan_wifi_2G_screen_on(self):
        """Measure power when WiFi is connected to 2.4 GHz and BLE is scanning

        Steps:
        1. Sets the phone in airplane mode, disables gestures and location
        2. BLE starts a balanced scan and WiFi is connected to 2.4 GHz
        3. Measures the power consumption
        4. Asserts pass/fail criteria based on measured power
        """
        # Set phone in the desired wireless mode
        self.brconfigs = wputils.setup_phone_wireless(
            test_class=self,
            bt_on='ON',
            wifi_on='ON',
            network=self.main_network[hc.BAND_2G],
            screen_status='ON')

        # Start BLE scan
        btutils.start_pmc_ble_scan(
            self.dut, ble_scan_settings_modes['opportunistic'],
            self.mon_info['offset'], self.mon_info['duration'])

        # Measure power
        self.measure_power()

    @test_tracker_info(uuid='87146825-787a-4ea7-9622-30e9286c8a76')
    def test_filter_ble_scan_low_power_wifi_2G_screen_off(self):
        """Measure power when WiFi is connected to 2.4 GHz and BLE is scanning

        Steps:
        1. Sets the phone in airplane mode, disables gestures and location
        2. BLE starts a filtered low power scan and WiFi is connected to 2G
        3. Measures the power consumption
        4. Asserts pass/fail criteria based on measured power
        """
        # Set phone in the desired wireless mode
        self.brconfigs = wputils.setup_phone_wireless(
            test_class=self,
            bt_on='ON',
            wifi_on='ON',
            network=self.main_network[hc.BAND_2G],
            screen_status='OFF')

        # Start BLE scan
        btutils.start_pmc_ble_scan(
            self.dut, ble_scan_settings_modes['low_power'],
            self.mon_info['offset'], self.mon_info['duration'])

        # Measure power
        self.measure_power()

    @test_tracker_info(uuid='2e645deb-b744-4272-8578-5d4cb159d5aa')
    def test_filter_ble_scan_low_power_wifi_5G_screen_off(self):
        """Measure power when WiFi is connected to 5 GHz and BLE is scanning

        Steps:
        1. Sets the phone in airplane mode, disables gestures and location
        2. BLE starts a filtered low power scan and WiFi is connected to 5G
        3. Measures the power consumption
        4. Asserts pass/fail criteria based on measured power
        """
        # Set phone in the desired wireless mode
        self.brconfigs = wputils.setup_phone_wireless(
            test_class=self,
            bt_on='ON',
            wifi_on='ON',
            network=self.main_network[hc.BAND_5G],
            screen_status='OFF')

        # Start BLE scan
        btutils.start_pmc_ble_scan(
            self.dut, ble_scan_settings_modes['low_power'],
            self.mon_info['offset'], self.mon_info['duration'])

        # Measure power
        self.measure_power()

    @test_tracker_info(uuid='d458bc41-f1c8-4ed6-a7b5-0bec34780dda')
    def test_wifi_scan_bt_on_screen_off(self):
        """Measure power when WiFi is scanning and BT is doing a page scan

        Steps:
        1. Sets the phone in airplane mode, disables gestures and location
        2. WiFi is scanning and BT is doing a page scan
        3. Measures the power consumption
        4. Asserts pass/fail criteria based on measured power
        """
        # Set phone in the desired wireless mode
        self.brconfigs = wputils.setup_phone_wireless(
            test_class=self,
            bt_on='ON',
            wifi_on='ON',
            network=self.main_network[hc.BAND_2G],
            screen_status='OFF')

        # Start WiFi connectivity scans
        self.dut.adb.shell_nb(self.PERIODIC_WIFI_SCAN)
        self.log.info('Started connectivity scans:')
        self.log.info(self.PERIODIC_WIFI_SCAN)

        # Measure power
        self.measure_power()

    @test_tracker_info(uuid='6d9c0e8e-6a0f-458b-84d2-7d60fc254170')
    def test_wifi_scan_ble_filter_low_power_scan_screen_off(self):
        """Measure power when WiFi is scanning and BLE is scanning

        Steps:
        1. Sets the phone in airplane mode, disables gestures and location
        2. WiFi is scanning and BLE is doing a low power filtered scan
        3. Measures the power consumption
        4. Asserts pass/fail criteria based on measured power
        """
        # Set phone in the desired wireless mode
        self.brconfigs = wputils.setup_phone_wireless(
            test_class=self,
            bt_on='ON',
            wifi_on='ON',
            network=self.main_network[hc.BAND_2G],
            screen_status='OFF')

        # Start BLE scan
        btutils.start_pmc_ble_scan(
            self.dut, ble_scan_settings_modes['low_power'],
            self.mon_info['offset'], self.mon_info['duration'])
        time.sleep(2)

        # Start WiFi connectivity scans
        self.dut.adb.shell_nb(self.PERIODIC_WIFI_SCAN)
        self.log.info('Started connectivity scans:')
        self.log.info(self.PERIODIC_WIFI_SCAN)

        # Measure power
        self.measure_power()

    @test_tracker_info(uuid='ba52317f-426a-4688-a0a5-1394bcc7b092')
    def test_wifi_scan_ble_filter_low_lat_scan_screen_off(self):
        """Measure power when WiFi is scanning and BLE is scanning

        Steps:
        1. Sets the phone in airplane mode, disables gestures and location
        2. WiFi is scanning and BLE is doing a low latency filtered scan
        3. Measures the power consumption
        4. Asserts pass/fail criteria based on measured power
        """
        # Set phone in the desired wireless mode
        self.brconfigs = wputils.setup_phone_wireless(
            test_class=self,
            bt_on='ON',
            wifi_on='ON',
            network=self.main_network[hc.BAND_2G],
            screen_status='OFF')

        # Start BLE scan
        btutils.start_pmc_ble_scan(
            self.dut, ble_scan_settings_modes['low_latency'],
            self.mon_info['offset'], self.mon_info['duration'])
        time.sleep(2)

        # Start WiFi connectivity scans
        self.dut.adb.shell_nb(self.PERIODIC_WIFI_SCAN)
        self.log.info('Started connectivity scans:')
        self.log.info(self.PERIODIC_WIFI_SCAN)

        # Measure power
        self.measure_power()

    @test_tracker_info(uuid='b4c63eac-bc77-4e76-afff-ade98dde4411')
    def test_wifi_pno_scan_ble_filter_low_lat_scan_screen_off(self):
        """Measure power when WiFi disconnected (PNO scan) and BLE is scanning

        Steps:
        1. Sets the phone in airplane mode, disables gestures and location
        2. WiFi is disconnected (PNOsscan) and BLE is doing a low latency
           filtered scan
        3. Measures the power consumption
        4. Asserts pass/fail criteria based on measured power
        """
        # Set phone in the desired wireless mode
        self.brconfigs = wputils.setup_phone_wireless(
            test_class=self,
            bt_on='ON',
            wifi_on='ON',
            network=self.main_network[hc.BAND_2G],
            screen_status='OFF')

        # Start BLE scan
        btutils.start_pmc_ble_scan(
            self.dut, ble_scan_settings_modes['low_latency'],
            self.mon_info['offset'], self.mon_info['duration'])
        time.sleep(1)

        # Set attenuator to make WiFi disconnect and start PNO scans
        self.log.info('Set attenuation so device loses connection')
        [
            self.attenuators[i].set_atten(
                self.atten_level[self.current_test_name][i])
            for i in range(self.num_atten)
        ]

        # Measure power
        self.measure_power()

    @test_tracker_info(uuid='798796dc-960c-42b2-a835-2b2aefa028d5')
    def test_cellular_verizon_on_wifi_scan_screen_off(self):
        """Measure power when cellular is ON, WiFi is scanning and BT is OFF

        Steps:
        1. Disables gestures and location
        2. WiFi is scanning and cellular is idle (Verizon)
        3. Measures the power consumption
        4. Asserts pass/fail criteria based on measured power
        """
        # Set phone in the desired wireless mode
        self.brconfigs = wputils.setup_phone_wireless(
            test_class=self,
            bt_on='OFF',
            wifi_on='ON',
            network=self.main_network[hc.BAND_5G],
            screen_status='OFF',
            regular_mode=True)

        # Start WiFi connectivity scans
        self.dut.adb.shell_nb(self.PERIODIC_WIFI_SCAN)
        self.log.info('Started connectivity scans:')
        self.log.info(self.PERIODIC_WIFI_SCAN)

        # Measure power
        self.measure_power()

    @test_tracker_info(uuid='6ae44d84-0e68-4524-99b2-d3bfbd2253b8')
    def test_cellular_on_wifi_scan_ble_backgnd_scan_low_power_screen_off(self):
        """Measure power when cellular is ON, WiFi and BLE are scanning

        Steps:
        1. Disables gestures and location
        2. WiFi is scanning and cellular is idle (Verizon) and BLE is doing
           a low power background scan
        3. Measures the power consumption
        4. Asserts pass/fail criteria based on measured power
        """
        # Set phone in the desired wireless mode
        self.brconfigs = wputils.setup_phone_wireless(
            test_class=self,
            bt_on='OFF',
            wifi_on='ON',
            network=self.main_network[hc.BAND_5G],
            screen_status='OFF',
            regular_mode=True)

        # Start BLE background scans
        self.dut.adb.shell(btutils.BLE_LOCATION_SCAN_ENABLE)
        time.sleep(1)
        self.dut.droid.bluetoothEnableBLE()
        time.sleep(2)
        self.dut.log.info('BLE is ON')
        btutils.start_pmc_ble_scan(
            self.dut, ble_scan_settings_modes['low_power'],
            self.mon_info['offset'], self.mon_info['duration'])
        time.sleep(2)

        # Start WiFi connectivity scans
        self.dut.adb.shell_nb(self.PERIODIC_WIFI_SCAN)
        self.log.info('Started connectivity scans:')
        self.log.info(self.PERIODIC_WIFI_SCAN)

        # Measure power
        self.measure_power()

    @test_tracker_info(uuid='2cb915a3-6319-4ac4-9e4d-9325b3b731c8')
    def test_cellular_on_wifi_scan_ble_backgnd_scan_low_lat_screen_off(self):
        """Measure power when cellular is ON, WiFi and BLE are scanning

        Steps:
        1. Disables gestures and location
        2. WiFi is scanning and cellular is idle (Verizon) and BLE is doing
           a low latency background scan
        3. Measures the power consumption
        4. Asserts pass/fail criteria based on measured power
        """
        # Set phone in the desired wireless mode
        self.brconfigs = wputils.setup_phone_wireless(
            test_class=self,
            bt_on='OFF',
            wifi_on='ON',
            network=self.main_network[hc.BAND_2G],
            screen_status='OFF',
            regular_mode=True)

        # Start BLE background scans
        self.dut.adb.shell(btutils.BLE_LOCATION_SCAN_ENABLE)
        time.sleep(1)
        self.dut.droid.bluetoothEnableBLE()
        time.sleep(2)
        self.dut.log.info('BLE is ON')
        btutils.start_pmc_ble_scan(
            self.dut, ble_scan_settings_modes['low_latency'],
            self.mon_info['offset'], self.mon_info['duration'])
        time.sleep(2)

        # Start WiFi connectivity scans
        self.dut.adb.shell_nb(self.PERIODIC_WIFI_SCAN)
        self.log.info('Started connectivity scans:')
        self.log.info(self.PERIODIC_WIFI_SCAN)

        # Measure power
        self.measure_power()
