# 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
import time

from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import site_eap_certs
from autotest_lib.client.common_lib.cros.network import iw_runner
from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
from autotest_lib.client.common_lib.cros.network import xmlrpc_security_types
from autotest_lib.server.cros.network import hostap_config
from autotest_lib.server.cros.network import wifi_cell_test_base


class network_WiFi_PMKSACaching(wifi_cell_test_base.WiFiCellTestBase):
    """Test that we use PMKSA caching where appropriate."""
    version = 1
    AP0_FREQUENCY = 2412
    AP1_FREQUENCY = 5220


    def dut_sees_bss(self, bssid):
        """
        Check if a DUT can see a BSS in scan results.

        @param bssid: string bssid of AP we expect to see in scan results.
        @return True iff scan results from DUT include the specified BSS.

        """
        runner = iw_runner.IwRunner(remote_host=self.context.client.host)
        is_requested_bss = lambda iw_bss: iw_bss.bss == bssid
        scan_results = runner.scan(self.context.client.wifi_if)
        return scan_results and filter(is_requested_bss, scan_results)


    def retry(self, func, reason, timeout_seconds=15):
        """
        Retry a function until it returns true or we time out.

        @param func: function that takes no parameters.
        @param reason: string concise description of what the function does.
        @param timeout_seconds: int number of seconds to wait for a True
                response from |func|.

        """
        logging.info('Waiting for %s.', reason)
        start_time = time.time()
        while time.time() - start_time < timeout_seconds:
            if func():
                return
            time.sleep(1)
        else:
            raise error.TestFail('Timed out waiting for %s.' % reason)


    def run_once(self):
        """Body of the test."""
        mode_n = hostap_config.HostapConfig.MODE_11N_PURE
        eap_config = xmlrpc_security_types.WPAEAPConfig(
                server_ca_cert=site_eap_certs.ca_cert_1,
                server_cert=site_eap_certs.server_cert_1,
                server_key=site_eap_certs.server_private_key_1,
                client_ca_cert=site_eap_certs.ca_cert_1,
                client_cert=site_eap_certs.client_cert_1,
                client_key=site_eap_certs.client_private_key_1,
                # PMKSA caching is only defined for WPA2.
                wpa_mode=xmlrpc_security_types.WPAConfig.MODE_PURE_WPA2)
        ap_config0 = hostap_config.HostapConfig(
                mode=mode_n, frequency=self.AP0_FREQUENCY,
                security_config=eap_config)
        self.context.configure(ap_config0)
        assoc_params = xmlrpc_datatypes.AssociationParameters(
                ssid=self.context.router.get_ssid(),
                security_config=eap_config)
        self.context.assert_connect_wifi(assoc_params)
        # Add another AP with identical configuration except in 5 Ghz.
        ap_config1 = hostap_config.HostapConfig(
                mode=mode_n, ssid=self.context.router.get_ssid(),
                frequency=self.AP1_FREQUENCY, security_config=eap_config)
        self.context.configure(ap_config1, multi_interface=True)
        bssid = self.context.router.get_hostapd_mac(1)
        has_roamed = lambda freq: self.context.client.get_iw_link_value(
                iw_runner.IW_LINK_KEY_FREQUENCY,
                ignore_failures=True) == str(freq)
        self.retry(lambda: self.dut_sees_bss(bssid), 'DUT to see second AP')
        self.context.client.request_roam(bssid)
        self.retry(lambda: has_roamed(self.AP1_FREQUENCY), 'roam to second AP')
        self.context.router.deconfig_aps(instance=1, silent=True)
        self.retry(lambda: has_roamed(self.AP0_FREQUENCY),
                   'fallback to first AP')
        self.context.router.confirm_pmksa_cache_use(instance=0)
