#!/usr/bin/python2

# 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.get_proxy()
    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.get_proxy()
    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.get_proxy()
    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)
