#!/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

import common
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.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.SubjectMatch': unicode,
    'EAP.UseSystemCAs': bool,
    wifi_proxy.WifiProxy.SERVICE_PROPERTY_SECURITY_CLASS: 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)
