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

from autotest_lib.client.common_lib import utils
from autotest_lib.client.cros.networking import shill_proxy


class WifiProxy(shill_proxy.ShillProxy):
    """Wrapper around shill dbus interface used by wifi tests."""


    def set_logging_for_wifi_test(self):
        """Set the logging in shill for a test of wifi technology.

        Set the log level to |ShillProxy.LOG_LEVEL_FOR_TEST| and the log scopes
        to the ones defined in |ShillProxy.LOG_SCOPES_FOR_TEST| for
        |ShillProxy.TECHNOLOGY_WIFI|.

        """
        self.set_logging_for_test(self.TECHNOLOGY_WIFI)


    def remove_all_wifi_entries(self):
        """Iterate over all pushed profiles and remove WiFi entries."""
        profiles = self.get_profiles()
        for profile in profiles:
            profile_properties = profile.GetProperties(utf8_strings=True)
            entries = profile_properties[self.PROFILE_PROPERTY_ENTRIES]
            for entry_id in entries:
                try:
                    entry = profile.GetEntry(entry_id)
                except dbus.exceptions.DBusException as e:
                    logging.error('Unable to retrieve entry %s:%r', entry_id, e)
                    continue
                if entry[self.ENTRY_FIELD_TYPE] == 'wifi':
                    profile.DeleteEntry(entry_id)


    def configure_wifi_service(self, ssid, security, security_parameters=None,
                               save_credentials=True, station_type=None,
                               hidden_network=False, guid=None,
                               autoconnect=None):
        """Configure a WiFi service.

        @param ssid string name of network to connect to.
        @param security string type of security used in network (e.g. psk)
        @param security_parameters dict of service property/value pairs that
            make up the credentials and settings for the given security
            type (e.g. the passphrase for psk security).
        @param save_credentials bool True if we should save EAP credentials.
        @param station_type string one of SUPPORTED_WIFI_STATION_TYPES.
        @param hidden_network bool True when the SSID is not broadcasted.
        @param guid string unique identifier for network.
        @param autoconnect bool or None.  None indicates that this should not
            be set one way or the other, while a boolean indicates a desired
            value.

        """
        # |mode| is derived from the station type we're attempting to join.  It
        # does not refer to the 802.11x (802.11a/b/g/n) type.  It refers to a
        # shill connection mode.
        mode = self.SUPPORTED_WIFI_STATION_TYPES[station_type]

        if security_parameters is None:
            security_parameters = {}

        config_params = {self.SERVICE_PROPERTY_TYPE: 'wifi',
                         self.SERVICE_PROPERTY_HIDDEN: hidden_network,
                         self.SERVICE_PROPERTY_SSID: ssid,
                         self.SERVICE_PROPERTY_SECURITY_CLASS: security,
                         self.SERVICE_PROPERTY_MODE: mode}
        if autoconnect is not None:
            config_params[self.SERVICE_PROPERTY_AUTOCONNECT] = autoconnect
        config_params.update(security_parameters)
        if guid is not None:
            config_params[self.SERVICE_PROPERTY_GUID] = guid
        try:
            self.configure_service(config_params)
        except dbus.exceptions.DBusException as e:
            logging.error('Caught an error while configuring a WiFi '
                          'service: %r', e)
            return False

        logging.info('Configured service: %s', ssid)
        return True


    def connect_to_wifi_network(self,
                                ssid,
                                security,
                                security_parameters,
                                save_credentials,
                                station_type=None,
                                hidden_network=False,
                                guid=None,
                                autoconnect=None,
                                discovery_timeout_seconds=15,
                                association_timeout_seconds=15,
                                configuration_timeout_seconds=15):
        """
        Connect to a WiFi network with the given association parameters.

        @param ssid string name of network to connect to.
        @param security string type of security used in network (e.g. psk)
        @param security_parameters dict of service property/value pairs that
                make up the credentials and settings for the given security
                type (e.g. the passphrase for psk security).
        @param save_credentials bool True if we should save EAP credentials.
        @param station_type string one of SUPPORTED_WIFI_STATION_TYPES.
        @param hidden_network bool True when the SSID is not broadcasted.
        @param guid string unique identifier for network.
        @param discovery_timeout_seconds float timeout for service discovery.
        @param association_timeout_seconds float timeout for service
            association.
        @param configuration_timeout_seconds float timeout for DHCP
            negotiations.
        @param autoconnect: bool or None.  None indicates that this should not
            be set one way or the other, while a boolean indicates a desired
            value.
        @return (successful, discovery_time, association_time,
                 configuration_time, reason)
            where successful is True iff the operation succeeded, *_time is
            the time spent waiting for each transition, and reason is a string
            which may contain a meaningful description of failures.

        """
        logging.info('Attempting to connect to %s', ssid)
        start_time = time.time()
        discovery_time = -1.0
        association_time = -1.0
        configuration_time = -1.0
        if station_type not in self.SUPPORTED_WIFI_STATION_TYPES:
            return (False, discovery_time, association_time,
                    configuration_time,
                    'FAIL(Invalid station type specified.)')

        # |mode| is derived from the station type we're attempting to join.  It
        # does not refer to the 802.11x (802.11a/b/g/n) type.  It refers to a
        # shill connection mode.
        mode = self.SUPPORTED_WIFI_STATION_TYPES[station_type]

        if hidden_network:
            logging.info('Configuring %s as a hidden network.', ssid)
            if not self.configure_wifi_service(
                    ssid, security, save_credentials=save_credentials,
                    station_type=station_type, hidden_network=True,
                    autoconnect=autoconnect):
                return (False, discovery_time, association_time,
                        configuration_time,
                        'FAIL(Failed to configure hidden SSID)')

            logging.info('Configured hidden service: %s', ssid)


        logging.info('Discovering...')
        discovery_params = {self.SERVICE_PROPERTY_TYPE: 'wifi',
                            self.SERVICE_PROPERTY_NAME: ssid,
                            self.SERVICE_PROPERTY_SECURITY_CLASS: security,
                            self.SERVICE_PROPERTY_MODE: mode}
        while time.time() - start_time < discovery_timeout_seconds:
            discovery_time = time.time() - start_time
            service_object = self.find_matching_service(discovery_params)
            if service_object:
                try:
                    service_properties = service_object.GetProperties(
                            utf8_strings=True)
                except dbus.exceptions.DBusException:
                    # This usually means the service handle has become invalid.
                    # Which is sort of like not getting a handle back from
                    # find_matching_service in the first place.
                    continue
                strength = self.dbus2primitive(
                        service_properties[self.SERVICE_PROPERTY_STRENGTH])
                if strength > 0:
                    logging.info('Discovered service: %s. Strength: %r.',
                                 ssid, strength)
                    break

            # This is spammy, but shill handles that for us.
            self.manager.RequestScan('wifi')
            time.sleep(self.POLLING_INTERVAL_SECONDS)
        else:
            return (False, discovery_time, association_time,
                    configuration_time, 'FAIL(Discovery timed out)')

        # At this point, we know |service| is in the service list.  Attempt
        # to connect it, and watch the states roll by.
        logging.info('Connecting...')
        try:
            for service_property, value in security_parameters.iteritems():
                service_object.SetProperty(service_property, value)
            if guid is not None:
                service_object.SetProperty(self.SERVICE_PROPERTY_GUID, guid)
            if autoconnect is not None:
                service_object.SetProperty(self.SERVICE_PROPERTY_AUTOCONNECT,
                                           autoconnect)
            service_object.Connect()
            logging.info('Called connect on service')
        except dbus.exceptions.DBusException, e:
            logging.error('Caught an error while trying to connect: %s',
                          e.get_dbus_message())
            return (False, discovery_time, association_time,
                    configuration_time, 'FAIL(Failed to call connect)')

        logging.info('Associating...')
        result = self.wait_for_property_in(
                service_object,
                self.SERVICE_PROPERTY_STATE,
                ('configuration', 'ready', 'portal', 'online'),
                association_timeout_seconds)
        (successful, _, association_time) = result
        if not successful:
            return (False, discovery_time, association_time,
                    configuration_time, 'FAIL(Association timed out)')

        logging.info('Associated with service: %s', ssid)

        logging.info('Configuring...')
        result = self.wait_for_property_in(
                service_object,
                self.SERVICE_PROPERTY_STATE,
                ('ready', 'portal', 'online'),
                configuration_timeout_seconds)
        (successful, _, configuration_time) = result
        if not successful:
            return (False, discovery_time, association_time,
                    configuration_time, 'FAIL(Configuration timed out)')

        logging.info('Configured service: %s', ssid)

        # Great success!
        logging.info('Connected to WiFi service.')
        return (True, discovery_time, association_time, configuration_time,
                'SUCCESS(Connection successful)')


    def disconnect_from_wifi_network(self, ssid, timeout=None):
        """Disconnect from the specified WiFi network.

        Method will succeed if it observes the specified network in the idle
        state after calling Disconnect.

        @param ssid string name of network to disconnect.
        @param timeout float number of seconds to wait for idle.
        @return tuple(success, duration, reason) where:
            success is a bool (True on success).
            duration is a float number of seconds the operation took.
            reason is a string containing an informative error on failure.

        """
        if timeout is None:
            timeout = self.SERVICE_DISCONNECT_TIMEOUT
        service_description = {self.SERVICE_PROPERTY_TYPE: 'wifi',
                               self.SERVICE_PROPERTY_NAME: ssid}
        service = self.find_matching_service(service_description)
        if service is None:
            return (False,
                    0.0,
                    'Failed to disconnect from %s, service not found.' % ssid)

        service.Disconnect()
        result = self.wait_for_property_in(service,
                                           self.SERVICE_PROPERTY_STATE,
                                           ('idle',),
                                           timeout)
        (successful, final_state, duration) = result
        message = 'Success.'
        if not successful:
            message = ('Failed to disconnect from %s, '
                       'timed out in state: %s.' % (ssid, final_state))
        return (successful, duration, message)


    def configure_bgscan(self, interface, method=None, short_interval=None,
                         long_interval=None, signal=None):
        """Configures bgscan parameters for wpa_supplicant.

        @param interface string name of interface to configure (e.g. 'mlan0').
        @param method string bgscan method (e.g. 'none').
        @param short_interval int short scanning interval.
        @param long_interval int normal scanning interval.
        @param signal int signal threshold.

        """
        device = self.find_object('Device', {'Name': interface})
        if device is None:
            logging.error('No device found with name: %s', interface)
            return False

        attributes = {'ScanInterval': (dbus.UInt16, long_interval),
                      'BgscanMethod': (dbus.String, method),
                      'BgscanShortInterval': (dbus.UInt16, short_interval),
                      'BgscanSignalThreshold': (dbus.Int32, signal)}
        for k, (type_cast, value) in attributes.iteritems():
            if value is None:
                continue

            # 'default' is defined in:
            # client/common_lib/cros/network/xmlrpc_datatypes.py
            # but we don't have access to that file here.
            if value == 'default':
                device.ClearProperty(k)
            else:
                device.SetProperty(k, type_cast(value))
        return True


    def get_active_wifi_SSIDs(self):
        """@return list of string SSIDs with at least one BSS we've scanned."""
        properties = self.manager.GetProperties(utf8_strings=True)
        services = [self.get_dbus_object(self.DBUS_TYPE_SERVICE, path)
                    for path in properties[self.MANAGER_PROPERTY_SERVICES]]
        wifi_services = []
        for service in services:
            try:
                service_properties = self.dbus2primitive(service.GetProperties(
                        utf8_strings=True))
            except dbus.exceptions.DBusException:
                pass  # Probably the service disappeared before GetProperties().
            logging.debug('Considering service with properties: %r',
                          service_properties)
            service_type = service_properties[self.SERVICE_PROPERTY_TYPE]
            strength = service_properties[self.SERVICE_PROPERTY_STRENGTH]
            if service_type == 'wifi' and strength > 0:
                # Note that this may cause terrible things if the SSID
                # is not a valid ASCII string.
                ssid = service_properties[self.SERVICE_PROPERTY_HEX_SSID]
                logging.info('Found active WiFi service: %s', ssid)
                wifi_services.append(ssid.decode('hex'))
        return wifi_services


    def wait_for_service_states(self, ssid, states, timeout_seconds):
        """Wait for a service (ssid) to achieve one of a number of states.

        @param ssid string name of network for whose state we're waiting.
        @param states tuple states for which to wait.
        @param timeout_seconds seconds to wait for property to be achieved
        @return tuple(successful, final_value, duration)
            where successful is True iff we saw one of |states|, final_value
            is the final state we saw, and duration is how long we waited to
            see that value.

        """
        discovery_params = {self.SERVICE_PROPERTY_TYPE: 'wifi',
                            self.SERVICE_PROPERTY_NAME: ssid}
        start_time = time.time()
        try:
            service_object = utils.poll_for_condition(
                    condition=lambda: self.find_matching_service(
                            discovery_params),
                    timeout=timeout_seconds,
                    sleep_interval=self.POLLING_INTERVAL_SECONDS,
                    desc='Find a matching service to the discovery params')

            return self.wait_for_property_in(
                    service_object,
                    self.SERVICE_PROPERTY_STATE,
                    states,
                    timeout_seconds - (time.time() - start_time))

        # poll_for_condition timed out
        except utils.TimeoutError:
            logging.error('Timed out waiting for %s states', ssid)
            return False, 'unknown', timeout_seconds
