# Copyright (c) 2013 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.

import logging

from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import utils
from autotest_lib.client.common_lib.cros.network import iw_runner
from autotest_lib.client.common_lib.cros.network import tcpdump_analyzer
from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
from autotest_lib.server.cros.network import hostap_config
from autotest_lib.server.cros.network import netperf_runner
from autotest_lib.server.cros.network import wifi_cell_test_base


class network_WiFi_RateControl(wifi_cell_test_base.WiFiCellTestBase):
    """
    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.

    """

    version = 1

    # We only care about the encoding/MCS index of the frames, not the
    # contents.  Large snaplens fill up /tmp/ and make shuffling the bits
    # around take longer.  However, we might be interested in the contents of
    # the frames in the association process, and packets I've seen with HT IEs
    # seem to come in around 300 bytes.
    TEST_SNAPLEN = 400


    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._ap_configs = additional_params


    def get_highest_mcs_rate(self, frequency):
        """
        Get the highest MCS index supported by the DUT on |frequency|.

        @param frequency: int frequency to look for supported MCS rates.
        @return int highest rate supported.

        """
        # Figure out the highest MCS index supported by this hardware.
        phys = iw_runner.IwRunner(
                remote_host=self.context.client.host).list_phys()
        if len(phys) != 1:
            raise error.TestFail('Test expects a single PHY, but we got %d' %
                                 len(phys))

        phy = phys[0]
        bands = [band for band in phy.bands if frequency in band.frequencies]
        if len(bands) != 1:
            raise error.TestFail('Test expects a single possible band for a '
                                 'given frequency, but this device has %d '
                                 'such bands.' % len(bands))

        # 32 is a special low throughput, high resilience mode.  Ignore it.
        possible_indices = filter(lambda x: x != 32, bands[0].mcs_indices)

        if not possible_indices:
            raise error.TestFail('No possible MCS indices on frequency %d' %
                                 frequency)

        return max(possible_indices)


    def check_bitrates_in_capture(self, pcap_result, max_mcs_index):
        """
        Check that frames in a packet capture have expected MCS indices.

        @param pcap_result: RemoteCaptureResult tuple.
        @param max_mcs_index: int MCS index representing the highest possible
                bitrate on this device.

        """
        logging.info('Analyzing packet capture...')
        pcap_filter = 'udp and ip src host %s' % self.context.client.wifi_ip
        frames = tcpdump_analyzer.get_frames(
                pcap_result.pcap_path,
                remote_host=self.context.router.host,
                pcap_filter=pcap_filter)

        logging.info('Grouping frames by MCS index')
        counts = {}
        for frame in frames:
            counts[frame.mcs_index] = counts.get(frame.mcs_index, 0) + 1
        logging.info('Saw WiFi frames with MCS indices: %r', counts)

        # Now figure out the index which the device sent the most packets with.
        dominant_index = None
        num_packets_sent = -1
        for index, num_packets in counts.iteritems():
            if num_packets > num_packets_sent:
                dominant_index = index
                num_packets_sent = num_packets

        # We should see that the device sent more frames with the maximal index
        # than anything else.  This checks that the rate controller is fairly
        # aggressive and using all of the device's capabilities.
        if dominant_index != max_mcs_index:
            raise error.TestFail('Failed to use best possible MCS '
                                 'index %d in a clean RF environment: %r' %
                                 (max_mcs_index, counts))


    def run_once(self):
        """Test body."""
        # Just abort the test if we're in the lab and not on a machine known
        # to be conducted.  This test assumes a really great RF environment.
        hostname = self.context.client.host.hostname
        if utils.host_is_in_lab_zone(hostname):
            in_grover_cell = hostname.startswith('chromeos1-grover-')
            if not self.context.client.conductive and not in_grover_cell:
                raise error.TestNAError(
                        'This test requires a great RF environment.')

        caps = [hostap_config.HostapConfig.N_CAPABILITY_GREENFIELD,
                hostap_config.HostapConfig.N_CAPABILITY_HT40]
        mode_11n = hostap_config.HostapConfig.MODE_11N_PURE
        get_config = lambda channel: hostap_config.HostapConfig(
                channel=channel, mode=mode_11n, n_capabilities=caps)
        netperf_config = netperf_runner.NetperfConfig(
                netperf_runner.NetperfConfig.TEST_TYPE_UDP_STREAM)
        for i, ap_config in enumerate([get_config(1), get_config(157)]):
            # Set up the router and associate the client with it.
            self.context.configure(ap_config)
            self.context.router.start_capture(
                    ap_config.frequency,
                    ht_type=ap_config.ht_packet_capture_mode,
                    snaplen=self.TEST_SNAPLEN)
            assoc_params = xmlrpc_datatypes.AssociationParameters(
                    ssid=self.context.router.get_ssid())
            self.context.assert_connect_wifi(assoc_params)
            with netperf_runner.NetperfRunner(self.context.client,
                                              self.context.router,
                                              netperf_config) as runner:
                runner.run()
            results = self.context.router.stop_capture()
            if len(results) != 1:
                raise error.TestError('Expected to generate one packet '
                                      'capture but got %d instead.' %
                                      len(results))

            # The device should sense that it is in a clean RF environment and
            # use the highest index to achieve maximal throughput.
            max_mcs_index = self.get_highest_mcs_rate(ap_config.frequency)
            self.check_bitrates_in_capture(results[0], max_mcs_index)
            # Clean up router and client state for the next run.
            self.context.client.shill.disconnect(self.context.router.get_ssid())
            self.context.router.deconfig()
