# Copyright 2017 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.server.cros.network import hostap_config
from autotest_lib.server.cros.network import wifi_cell_test_base

class network_WiFi_Reset(wifi_cell_test_base.WiFiCellTestBase):
    """Test that the WiFi interface can be reset successfully, and that WiFi
    comes back up properly. Supports only Marvell (mwifiex) Wifi drivers.
    """

    version = 1

    _MWIFIEX_RESET_PATH = "/sys/kernel/debug/mwifiex/%s/reset"
    _NUM_RESETS = 15


    @property
    def mwifiex_reset_path(self):
        """Get path to the Wifi interface's reset file."""
        return self._MWIFIEX_RESET_PATH % self.context.client.wifi_if


    def poll_for_condition(self, condition, timeout=20, interval=0.5):
        """Helper for polling for some condition.

        @param condition: a condition function for checking the state we're
                          polling; should return True for success, False for
                          failure
        @param timeout: max number of seconds to poll for
        @param interval: polling interval, in seconds

        @returns: False if timed out waiting for condition; True otherwise
        """
        start_time = time.time()
        while time.time() - start_time < timeout:
            if condition():
                return True
            time.sleep(interval)
        return False


    def mwifiex_reset_exists(self):
        """Check if the mwifiex reset file is present (i.e., a mwifiex
        interface is present).
        """
        return self.context.client.host.run('test -e "%s"' %
                self.mwifiex_reset_path, ignore_status=True).exit_status == 0


    def mwifiex_reset(self, client):
        """Perform mwifiex reset, and wait for the interface to come back up.

        @returns: True if interface comes back up successfully; False for
        errors (e.g., timeout)
        """

        ssid = self.context.router.get_ssid()

        # Adapter will asynchronously reset.
        self.context.client.host.run('echo 1 > ' + self.mwifiex_reset_path)

        # Wait for disconnect. We aren't guaranteed to receive a disconnect
        # event, but shill will at least notice the adapter went away.
        self.context.client.wait_for_service_states(ssid, ['idle'],
                timeout_seconds=20)

        # Now wait for the reset interface file to come back.
        if not self.poll_for_condition(self.mwifiex_reset_exists):
            logging.error("Failed, waiting for interface to reappear")
            return False

        return True


    def run_once(self):
        """Body of the test."""

        if not self.mwifiex_reset_exists():
            self._supports_reset = False
            raise error.TestNAError('DUT does not support device reset')
        else:
            self._supports_reset = True

        client = self.context.client
        ap_config = hostap_config.HostapConfig(channel=1)
        ssid = self.configure_and_connect_to_ap(ap_config)

        self.context.assert_ping_from_dut()

        router = self.context.router
        ssid = router.get_ssid()

        logging.info("Running %d resets", self._NUM_RESETS)
        for i in range(self._NUM_RESETS):
            if not self.mwifiex_reset(client):
                raise error.TestFail('Failed to reset device %s' %
                                     client.wifi_if)

            client.wait_for_connection(ssid)
            self.context.assert_ping_from_dut()


    def cleanup(self):
        """Performs cleanup at exit. May reboot the DUT, to keep the system
        functioning for the next test.
        """

        if self._supports_reset and not self.mwifiex_reset_exists():
            logging.info("Test exited, but interface is missing; rebooting")
            self.context.client.reboot(timeout=60)
