#!/usr/bin/python

# 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 sys

from autotest_lib.client.cros.networking import wifi_proxy

SERVICE_PROP_PARSERS = {
    'EAP.AnonymousIdentity': unicode,
    'EAP.CACertID': unicode,
    'EAP.CACertNSS': unicode,
    'EAP.CACertPEM': unicode,
    'EAP.CACert': unicode,
    'EAP.CertID': unicode,
    'EAP.ClientCert': unicode,
    'EAP.EAP': unicode,
    'EAP.Identity': unicode,
    'EAP.InnerEAP': unicode,
    'EAP.KeyID': unicode,
    'EAP.KeyMgmt': unicode,
    'EAP.Password': unicode,
    'EAP.PIN': unicode,
    'EAP.PrivateKey': unicode,
    'EAP.SubjectMatch': unicode,
    'EAP.UseSystemCAs': bool,
    wifi_proxy.WifiProxy.SERVICE_PROPERTY_SECURITY: unicode,
    }


def usage():
    """ Prints a usage message and returns False. """
    cmd = sys.argv[0]
    print 'Usage:'
    print cmd, 'connect <ssid> [passphrase] [security]'
    print '    |security| defaults to "psk" when |passphrase|',
    print 'is given without |security|'
    print
    print cmd, 'disconnect <ssid> [timeout seconds]'
    print
    print cmd, 'connect_with_props <ssid> <timeout seconds>'
    print '    <Security=[none|psk|802_1x]> [Property=Value ...]'
    print '    for Property in:'
    print '\n'.join(['\t\t' + x for x in sorted(SERVICE_PROP_PARSERS.keys())])
    print
    print cmd, 'configure <ssid> [passphrase] [security]'
    print '    |security| defaults to "psk" when |passphrase|',
    print 'is given without |security|'
    return False


def configure(ssid, security, passphrase):
    wifi = wifi_proxy.WifiProxy()
    security_parameters = {}
    if passphrase is not None:
        security_parameters[wifi.SERVICE_PROPERTY_PASSPHRASE] = passphrase
    successful = wifi.configure_wifi_service(ssid, security,
                                             security_parameters)
    if successful:
        print 'Operation succeeded.'
    else:
        print 'Operation failed.'
    return successful


def connect(ssid, security, credentials, save_credentials, timeout=15):
    """Attempt to connect to a WiFi network.

    Blocks until we connect successfully to a WiFi network described
    by the given parameters or time out while attempting to do so.

    @param ssid string Name of the network to connect to.
    @param security string security type of the network to connect to.
    @param credentials dict of service properties that includes credentials
            like the passphrase for psk security.
    @param save_credentials bool True if credentials should be saved.
    @return True upon success, False otherwise.

    """
    wifi = wifi_proxy.WifiProxy()
    result = wifi.connect_to_wifi_network(ssid,
            security,
            credentials,
            save_credentials,
            discovery_timeout_seconds=timeout,
            association_timeout_seconds=timeout,
            configuration_timeout_seconds=timeout)
    (successful, discovery, association, configuration, reason) = result
    if successful:
        print 'Operation succeeded.'
    else:
        print 'Operation failed. (%s)' % reason
    print 'Discovery time: %f.' % discovery
    print 'Association time: %f.' % association
    print 'Configuration time: %f.' % configuration
    return successful


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

    Disconnect from a network with name |ssid|.  Note that this
    method will not fail if we're already disconnected.

    @param ssid string Name of the network to disconnect from.
    @param timeout float number of seconds to wait for transition
            to idle state.
    @return True upon seeing network is in idle state.

    """
    wifi = wifi_proxy.WifiProxy()
    result = wifi.disconnect_from_wifi_network(ssid, timeout)
    (successful, duration, reason) = result
    if successful:
        print 'Operation succeeded.'
    else:
        print 'Operation failed: %s.' % reason
    print 'Disconnect time: %f.' % duration
    return successful


def parse_security_from_credentials(credentials):
    """Parses SERVICE_PROPERTY_SECURITY from credentials.

    @param credentials dict of service properties that includes credentials
            like the passphrase for psk security.
    @return SERVICE_PROPERTY_SECURITY value from credentials,
            or exit if no such key/value in credentials.

    """
    security = credentials.pop(
            wifi_proxy.WifiProxy.SERVICE_PROPERTY_SECURITY, None)
    if security is None:
        print "Error: security type not provided"
        usage()
        sys.exit(1)

    if security not in ['none', 'wep', 'psk', '802_1x']:
        print "Error: invalid security type %s" % security
        usage()
        sys.exit(1)

    return security


def parse_service_property(property_string):
    """Parses one commandline key=value string into a tuple.

    @param property_string string to be parsed into (key,value).
    @return parsed tuple of (key,value) or exit on parsing error.

    """
    property_name, raw_value = property_string.split('=', 1)

    if not property_name in SERVICE_PROP_PARSERS:
        print '%s is not a recognized service property' % property_name
        usage()
        sys.exit(1)

    try:
        return property_name, SERVICE_PROP_PARSERS[property_name](raw_value)
    except:
        print 'Failed parsing value from %s' % property_string
        usage()
        sys.exit(1)


def main(args):
    """Main method for this script.

    @param args list of arguments to the script, not including script name.
    @return True on success, False otherwise.

    """
    if len(args) < 2:
        return usage()
    command = args[0]
    ssid = args[1]
    save_credentials = True

    if command == 'configure':
        security = 'none'
        passphrase = None
        if len(args) > 2:
            security = 'psk'
            passphrase = args[2]
        if len(args) > 3:
            security = args[3]
        return configure(ssid, security, passphrase)

    if command == 'connect':
        security = 'none'
        credentials = {}
        save_credentials = True
        if len(args) > 2:
            credentials[wifi_proxy.WifiProxy.SERVICE_PROPERTY_PASSPHRASE] = \
                    args[2]
            security = 'psk'
        if len(args) > 3:
            security = args[3]
        return connect(ssid, security, credentials, save_credentials)

    if command == 'connect_with_props':
        timeout = float(args[2])
        credentials = {}
        if len(args) > 3:
            for i in xrange(3, len(args)):
                credentials.update((parse_service_property(args[i]),))
        security = parse_security_from_credentials(credentials)
        return connect(ssid, security, credentials, save_credentials, timeout)

    if command == 'disconnect':
        timeout=None
        if len(args) > 2:
            timeout = float(args[2])
        return disconnect(ssid, timeout)

    return usage()


if __name__ == '__main__':
    if not main(sys.argv[1:]):
      sys.exit(1)
