# Lint as: python2, python3
# Copyright 2015 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
import threading
import time

from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros.network import interface
from autotest_lib.server.cros.network import expected_performance_results
from autotest_lib.client.common_lib.cros.network import ping_runner
from autotest_lib.server.cros.network import perf_test_manager as perf_manager
from autotest_lib.server.cros.network import wifi_cell_perf_test_base

from autotest_lib.server.cros.bluetooth.bluetooth_adapter_quick_tests import \
     BluetoothAdapterQuickTests
from autotest_lib.server.cros.bluetooth.bluetooth_adapter_audio_tests import \
     BluetoothAdapterAudioTests
from autotest_lib.client.cros.bluetooth.bluetooth_audio_test_data import A2DP


class network_WiFi_BluetoothStreamPerf(
        wifi_cell_perf_test_base.WiFiCellPerfTestBase,
        BluetoothAdapterQuickTests, BluetoothAdapterAudioTests):
    """Test maximal achievable bandwidth on several channels per band.

    Conducts a performance test for a set of specified router configurations
    and reports results as keyval pairs.

    """

    test_wrapper = BluetoothAdapterQuickTests.quick_test_test_decorator
    batch_wrapper = BluetoothAdapterQuickTests.quick_test_batch_decorator

    version = 1

    PERF_TEST_TYPES = [
            perf_manager.PerfTestTypes.TEST_TYPE_TCP_TX,
            perf_manager.PerfTestTypes.TEST_TYPE_TCP_RX,
            perf_manager.PerfTestTypes.TEST_TYPE_TCP_BIDIRECTIONAL,
            perf_manager.PerfTestTypes.TEST_TYPE_UDP_TX,
            # TODO(b:251380100): investigate unstable results for UDP_RX
            # perf_manager.PerfTestTypes.TEST_TYPE_UDP_RX,
            perf_manager.PerfTestTypes.TEST_TYPE_UDP_BIDIRECTIONAL,
    ]

    BT_STREAMING_DURATION = 60

    def parse_additional_arguments(self, commandline_args, additional_params):
        """Hook into super class to take control files parameters.

        @param commandline_args dict of parsed parameters from the autotest.
        @param additional_params list of HostapConfig objects.

        """
        self._should_required = 'should' in commandline_args

        super(network_WiFi_BluetoothStreamPerf, self).parse_additional_arguments(
                commandline_args)

        self._ap_configs, self._use_iperf = additional_params

    def verify_result(self, result_drop, should_expected_drop,
                      must_expected_drop, board_expected_drop, test_type,
                      failed_test_types, ap_config_tag, bt_tag):
        """Verfiy that performance test result passes the must and should
        throughput requirements.

        @param result: the throughput result object
        @param must_expected_throughput: the min must expected throughput
        @param should_expected_throughput: the min should expected throughput
        @param test_type: the performance_test_types test type
        @param failed_test_types: a set of failed test_types
        @param power_save: powersaving configuration
        @param ap_config: the AP configuration
        @param bt_tag: string for BT operation

        """
        must_drop_failed = False
        should_drop_failed = False

        # If the must requirement is smaller than our maximum expectation for a
        # board, use the board specific maximum expectation instead of the must
        # requirement.
        if board_expected_drop and board_expected_drop > must_expected_drop:
            must_expected_drop = board_expected_drop

        if result_drop > must_expected_drop:
            logging.error(
                    'Throughput drop is too big for %s. Expected (must) %d %%, got %d.',
                    test_type, must_expected_drop, result_drop)
            must_drop_failed = True
        if result_drop > should_expected_drop:
            if self._should_required:
                logging.error(
                        'Throughput drop is too big for %s. Expected (should) %d %%, got %d.',
                        test_type, should_expected_drop,
                        result_drop)
                should_drop_failed = True
            else:
                logging.info(
                        'Throughput drop is bigger then expectation for %s. Expected (should) %d %%, got %d.',
                        test_type, should_expected_drop,
                        result_drop)
        if must_drop_failed or should_drop_failed:
            failed_test_type_list = [
                    '[test_type=%s' % test_type,
                    'ap_config_tag=%s' % ap_config_tag,
                    'bt_tag=%s' % bt_tag,
                    'measured_drop=%d' % result_drop
            ]
            if must_drop_failed:
                failed_test_type_list.append(
                        'must_expected_drop_failed=%d' %
                        must_expected_drop)
            elif should_drop_failed:
                failed_test_type_list.append(
                        'should_expected_drop_failed=%d' %
                        should_expected_drop)
            failed_test_types.add(', '.join(failed_test_type_list) + ']')

    def test_one(self, manager, session, config, test_type, failed_test_types, ap_config, ap_config_tag, bt_tag):
        """Run one iteration of wifi testing.

        @param manager: a PerfTestManager instance
        @param session: NetperfSession or IperfSession session
        @param config: NetperfConfig or IperfConfig config
        @param test_type: the performance_test_types test type
        @param failed_test_types: a set of failed test_types
        @param ap_config: the AP configuration
        @param ap_config_tag: string for AP configuration
        @param bt_tag: string for BT operation

        """
        get_ping_config = lambda period: ping_runner.PingConfig(
                self.context.get_wifi_addr(),
                interval=1,
                count=period,
                source_iface=self.context.client.wifi_if)

        logging.info('testing config %s, ap_config %s, BT:%s',
                     test_type, ap_config_tag, bt_tag)
        test_str = '_'.join([ap_config_tag, bt_tag])
        time.sleep(1)

        # Record the signal level.
        signal_level = self.context.client.wifi_signal_level
        signal_description = '_'.join(['signal', test_str])
        self.write_perf_keyval({signal_description: signal_level})

        # Run perf tool and log the results.
        results = session.run(config)
        if not results:
            logging.error('Failed to take measurement for %s',
                          config.test_type)
            return
        values = [result.throughput for result in results]
        self.output_perf_value(config.test_type + '_' + bt_tag,
                               values,
                               units='Mbps',
                               higher_is_better=True,
                               graph=ap_config_tag)
        result = manager.get_result(results, config)
        self.write_perf_keyval(
                result.get_keyval(
                        prefix='_'.join([config.test_type, test_str])))

        # Log the standard deviation
        throughput_dev = result.throughput_dev
        self.output_perf_value(config.test_type + '_' + bt_tag + '_dev',
                               throughput_dev,
                               units='Mbps',
                               higher_is_better=False,
                               graph=ap_config_tag + '_dev')
        self.write_perf_keyval(
            {'_'.join([config.test_type, test_str, 'dev']): throughput_dev})

        # Log the drop in throughput compared with the 'BT_disconnected'
        # baseline. Only positive values are valid. Report the drop as a
        # whole integer percentage of (base_through-through)/base_through.
        if bt_tag == BluetoothAdapterAudioTests.CONNECTION_STATE_DISCONNECTED:
            self.base_through = result.throughput
        elif self.base_through > 0:
            expected_drop = expected_performance_results.get_expected_wifibt_coex_throughput_drop(
                    test_type, ap_config, bt_tag)

            board_expected_drop = expected_performance_results.get_board_max_wifibt_coex_throughput_drop_expectation(
                test_type, self.context.client.board, ap_config, bt_tag)

            drop = int( (self.base_through - result.throughput) * 100 /
                        self.base_through)
            self.output_perf_value(test_type + '_' + bt_tag + '_drop',
                                   drop,
                                   units='percent_drop',
                                   higher_is_better=False,
                                   graph=ap_config_tag + '_drop')
            self.verify_result(drop, expected_drop[0],
                               expected_drop[1], board_expected_drop, test_type,
                               failed_test_types, ap_config_tag, bt_tag)
            self.write_perf_keyval(
                    {'_'.join([config.test_type, test_str, 'drop']): drop})
            logging.info('logging drop value as %d%%', drop)

        # Test latency with ping.
        result_ping = self.context.client.ping(get_ping_config(3))
        self.write_perf_keyval(
            { '_'.join(['ping', test_str]): result_ping.avg_latency })
        logging.info('Ping statistics with %s: %r', bt_tag, result_ping)

        return failed_test_types

    def pair_audio_device(self, device):
        """Pair an audio device pre-test to simplify later re-connection"""
        self.test_device_set_discoverable(device, True)
        self.test_discover_device(device.address)
        self.test_pairing(device.address, device.pin, trusted=True)
        device.SetTrustedByRemoteAddress(self.bluetooth_facade.address)
        self.test_disconnection_by_adapter(device.address)

    def do_audio_test(self, device):
        """Run the body of the audio test"""
        self.test_a2dp_sinewaves(device, A2DP, self.BT_STREAMING_DURATION)

    def do_run(self, ap_config, manager, power_save, governor):
        """Run a single set of perf tests, for a given AP and DUT config.

        @param ap_config: the AP configuration that is being used
        @param manager: a PerfTestManager instance
        @param power_save: whether or not to use power-save mode on the DUT
                           (boolean)
        @ return set of failed configs
        """
        governor_name = self.setup_governor(governor)
        # If CPU governor is already set to self._governor, don't
        # perform the run twice
        if governor_name == self._governor:
            return

        failed_test_types = set()

        self.context.client.powersave_switch(power_save)
        ps_tag = 'PS%s' % ('on' if power_save else 'off')
        governor_tag = 'governor-%s' % governor_name
        ap_config_tag = '_'.join([ap_config.perf_loggable_description,
                                  ps_tag, governor_tag])

        device = self.bt_device

        for test_type in self.PERF_TEST_TYPES:
            config = manager.get_config(test_type, self._is_openwrt)
            pcap_lan_iface = interface.Interface(self._pcap_lan_iface_name,
                                                 self.context.pcap_host.host)
            session = manager.get_session(test_type,
                                          self.context.client,
                                          self.context.pcap_host,
                                          peer_device_interface=pcap_lan_iface)

            session.MEASUREMENT_MAX_SAMPLES = int(self.BT_STREAMING_DURATION / 10)

            self.base_through = 0
            self.test_one(
                    manager, session, config, test_type, None, ap_config,
                    ap_config_tag,
                    BluetoothAdapterAudioTests.CONNECTION_STATE_DISCONNECTED)

            self.test_connection_by_device(device)
            failed_test_types.update(
                    self.test_one(
                            manager, session, config, test_type,
                            failed_test_types, ap_config, ap_config_tag,
                            BluetoothAdapterAudioTests.CONNECTION_STATE_CONNECTED))

            # Start playing audio in background
            audio_thread = threading.Thread(target=self.do_audio_test,
                                            args=(device, ))
            audio_thread.start()
            failed_test_types.update(
                    self.test_one(
                            manager, session, config, test_type,
                            failed_test_types, ap_config, ap_config_tag,
                            BluetoothAdapterAudioTests.CONNECTION_STATE_STREAMING))

            # Wait for audio thread to complete
            audio_thread.join()

            self.test_disconnection_by_adapter(device.address)
            failed_test_types.update(
                    self.test_one(
                            manager, session, config, test_type,
                            failed_test_types, ap_config, ap_config_tag,
                            BluetoothAdapterAudioTests.CONNECTION_STATE_DISCONNECTED_AGAIN))

        if governor:
            self.restore_scaling_governors()

        return failed_test_types

    @test_wrapper('Coex tests', devices={'BLUETOOTH_AUDIO': 1})
    def coex_test(self):
        """Test body."""
        start_time = time.time()
        self.bt_device = self.devices['BLUETOOTH_AUDIO'][0]
        self.initialize_bluetooth_audio(self.bt_device, A2DP)
        self.pair_audio_device(self.bt_device)

        high_drop_tests = self.configure_and_run_tests()

        self.cleanup_bluetooth_audio(self.bt_device, A2DP)
        end_time = time.time()
        logging.info('Running time %0.1f seconds.', end_time - start_time)
        if len(high_drop_tests) != 0:
            high_drop_tags = list(high_drop_tests)
            raise error.TestFail(
                    'Throughput drop level too high for test type(s): %s' %
                    ', '.join(high_drop_tags))

    @batch_wrapper('Coex batch')
    def coex_health_batch_run(self, num_iterations=1, test_name=None):
        """Run the bluetooth coex health test batch or a specific given test.

        @param num_iterations: how many iterations to run
        @param test_name: specific test to run otherwise None to run the
                whole batch
        """
        self.coex_test()

    def run_once(self, host, test_name=None, args_dict=None):
        self.host = host

        self.quick_test_init(host, use_btpeer=True, args_dict=args_dict)
        self.coex_health_batch_run(test_name=test_name)
        self.quick_test_cleanup()
