#!/usr/bin/env python3
# Copyright 2019 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.

from __future__ import print_function

import sys

import dbus
import flimflam

bus = dbus.SystemBus()

manager = dbus.Interface(bus.get_object('org.chromium.flimflam', '/'),
                         'org.chromium.flimflam.Manager')

if len(sys.argv) < 2:
    print('Usage: %s <command>' % (sys.argv[0]))
    print('')
    print('  state')
    print('  recheck-portal')
    print('  services')
    print('  passphrase <service> [passphrase]')
    print('  autoconnect <service> [autoconnect]')
    print('  connect <service>')
    print('  disconnect <service>')
    print('  remove <service>')
    print('')
    print('  scan [type]')
    print('  enable <type>')
    print('  disable <type>')
    print('')
    print('  dev <interface>')
    print('  dev <interface> networks')
    print('  dev <interface> connect <network>')
    print('  dev <interface> disconnect [network]')
    print('  dev <interface> powered [on|off]')
    sys.exit(1)


def print_properties(object_path, properties):
    print('[ %s ]' % (object_path))
    for key in properties.keys():
        if key == 'Networks':
            continue

        if key in ['Powered', 'Scanning', 'Connected',
                   'Available', 'Remember', 'Default']:
            if properties[key] == dbus.Boolean(1):
                val = 'true'
            else:
                val = 'false'
        elif key in ['Strength', 'Priority']:
            val = int(properties[key])
        else:
            val = str(properties[key])

        print('     %s = %s' % (key, val))


def print_networks(networks):
    for object_path in networks:
        network = dbus.Interface(
            bus.get_object('org.chromium.flimflam', object_path),
            'org.chromium.flimflam.Network')

        properties = network.GetProperties()

        if properties['Connected'] == dbus.Boolean(1):
            connected = '*'
        else:
            connected = ' '

        if 'Name' in properties.keys():
            name = properties['Name']
        else:
            name = ''

        strength = int(properties['Strength'])

        details = ''
        try:
            details += '{' + properties['WiFi.Mode'] + '} '
        except Exception:
            pass
        try:
            details += '{' + properties['WiFi.Security'] + '} '
        except Exception:
            pass
        if 'WiFi.Passphrase' in properties.keys():
            if properties['WiFi.Passphrase'] != '':
                details += '{passphrase present}'

        print('%s %-26s %3d%%  %s' % (connected, name, strength, details))


def select_network(networks, name):
    for object_path in networks:
        network = dbus.Interface(
            bus.get_object('org.chromium.flimflam', object_path),
            'org.chromium.flimflam.Network')

        properties = network.GetProperties()

        if properties['Name'] != name:
            continue

        if properties['Connected'] == dbus.Boolean(1):
            print('Already connected to network %s' % (name))
            break

        print('Selecting network %s' % (name))

        network.Connect()


def disconnect_network(networks, name):
    for object_path in networks:
        network = dbus.Interface(
            bus.get_object('org.chromium.flimflam', object_path),
            'org.chromium.flimflam.Network')

        properties = network.GetProperties()

        if name != '' and properties['Name'] != name:
            continue

        if properties['Connected'] == dbus.Boolean(1):
            name = properties['Name']
            print('Disconnecting from network %s' % (name))
            network.Disconnect()


def print_services(services):
    for object_path in services:
        service = dbus.Interface(
            bus.get_object('org.chromium.flimflam', object_path),
            'org.chromium.flimflam.Service')

        properties = service.GetProperties()

        identifier = object_path[object_path.rfind('/') + 1:]

        if properties['IsConnected'] == dbus.Boolean(1):
            connected = '*'
        else:
            connected = ' '

        if 'Name' in properties.keys():
            name = properties['Name']
        else:
            name = '{' + properties['Type'] + '}'

        print('%s %-26s { %s }' % (connected, name, identifier))


def main():
    if sys.argv[1] == 'state':
        properties = manager.GetProperties()

        print('System is %s' % (properties['State']))

    elif sys.argv[1] == 'recheck-portal':
        manager.RecheckPortal()
        print('Rechecking portal state')

    elif sys.argv[1] in ['services', 'list', 'show']:
        properties = manager.GetProperties()

        print_services(properties['Services'])

    elif sys.argv[1] in ['passphrase', 'pass']:
        if len(sys.argv) < 3:
            print('Need at least service parameter')
            sys.exit(1)

        path = '/profile/default/' + sys.argv[2]

        service = dbus.Interface(bus.get_object('org.chromium.flimflam', path),
                                 'org.chromium.flimflam.Service')

        if len(sys.argv) > 3:
            passphrase = sys.argv[3]

            service.SetProperty('Passphrase', passphrase)

            print('Passphrase %s set for %s' % (passphrase, sys.argv[2]))
        else:
            properties = service.GetProperties()

            if 'Name' in properties.keys():
                name = properties['Name']
            else:
                name = '{' + properties['Type'] + '}'

            if 'Passphrase' in properties.keys():
                passphrase = properties['Passphrase']
            else:
                passphrase = 'not set'

            print('Passphrase for %s is %s' % (name, passphrase))

    elif sys.argv[1] in ['autoconnect', 'autoconn']:
        if len(sys.argv) < 3:
            print('Need at least service parameter')
            sys.exit(1)

        path = '/profile/default/' + sys.argv[2]

        service = dbus.Interface(bus.get_object('org.chromium.flimflam', path),
                                 'org.chromium.flimflam.Service')

        if len(sys.argv) > 3:
            autoconnect = flimflam.make_dbus_boolean(sys.argv[3])

            service.SetProperty('AutoConnect', autoconnect)

            print('Auto connect %s for %s' % (autoconnect, sys.argv[2]))
        else:
            properties = service.GetProperties()

            if 'Name' in properties.keys():
                name = properties['Name']
            else:
                name = '{' + properties['Type'] + '}'

            if 'AutoConnect' in properties.keys():
                autoconnect = properties['AutoConnect']
            else:
                autoconnect = dbus.Boolean(0)

            print('Auto connect %s for %s' % (autoconnect, name))

    elif sys.argv[1] in ['connect', 'conn']:
        if len(sys.argv) < 3:
            print('Need at least service parameter')
            sys.exit(1)

        path = '/profile/default/' + sys.argv[2]

        service = dbus.Interface(bus.get_object('org.chromium.flimflam', path),
                                 'org.chromium.flimflam.Service')

        try:
            service.Connect(timeout=60000)
        except dbus.DBusException as error:
            print('%s: %s' % (error.get_dbus_name(), error.message))

    elif sys.argv[1] in ['disconnect', 'disc']:
        if len(sys.argv) < 3:
            print('Need at least service parameter')
            sys.exit(1)

        path = '/profile/default/' + sys.argv[2]

        service = dbus.Interface(bus.get_object('org.chromium.flimflam', path),
                                 'org.chromium.flimflam.Service')

        try:
            service.Disconnect()
        except dbus.DBusException as error:
            print('%s: %s' % (error.get_dbus_name(), error.message))

    elif sys.argv[1] in ['remove']:
        if len(sys.argv) < 3:
            print('Need at least service parameter')
            sys.exit(1)

        path = '/profile/default/' + sys.argv[2]

        service = dbus.Interface(bus.get_object('org.chromium.flimflam', path),
                                 'org.chromium.flimflam.Service')

        properties = service.GetProperties()

        try:
            service.Remove()
        except dbus.DBusException as error:
            print('%s: %s' % (error.get_dbus_name(), error.message))

    elif sys.argv[1] == 'scan':
        if len(sys.argv) > 2:
            manager.RequestScan(sys.argv[2])
        else:
            manager.RequestScan('')

    elif sys.argv[1] == 'enable':
        if len(sys.argv) > 2:
            manager.EnableTechnology(sys.argv[2])
        else:
            manager.EnableTechnology('')

    elif sys.argv[1] == 'disable':
        if len(sys.argv) > 2:
            manager.DisableTechnology(sys.argv[2])
        else:
            manager.DisableTechnology('')

    elif sys.argv[1] == 'dev':
        properties = manager.GetProperties()

        interface = ''
        command = ''
        value = ''

        if len(sys.argv) > 2:
            interface = sys.argv[2]
            if len(sys.argv) > 3:
                command = sys.argv[3]
                if len(sys.argv) > 4:
                    value = sys.argv[4]

        for path in properties['Devices']:
            device = dbus.Interface(
                bus.get_object('org.chromium.flimflam', path),
                'org.chromium.flimflam.Device')

            properties = device.GetProperties()

            if (interface != '' and
                properties.get('Interface', '') != interface and
                    path != interface):
                continue

            if command in ['networks', 'net']:
                if 'Networks' in properties.keys():
                    print_networks(properties['Networks'])
                else:
                    print('Device has no networks')
            elif command in ['connect', 'conn'] and value != '':
                if 'Networks' in properties.keys():
                    select_network(properties['Networks'], value)
                else:
                    print("Device can't connect networks")
            elif command in ['connect', 'conn']:
                print('Need to specify network')
            elif command in ['disconnect', 'disc'] and value != '':
                if 'Networks' in properties.keys():
                    disconnect_network(properties['Networks'], value)
                else:
                    print('Device has no networks')
            elif command in ['discconnect', 'disc']:
                if 'Networks' in properties.keys():
                    disconnect_network(properties['Networks'], '')
                else:
                    print('Device has no networks')
            elif command == 'powered' and value != '':
                powered = flimflam.make_dbus_boolean(value)
                device.SetProperty('Powered', powered)
            elif command == 'powered':
                interface = properties.get('Interface', 'unknown')
                if properties['Powered'] == dbus.Boolean(1):
                    powered = 'on'
                else:
                    powered = 'off'
                print('Device %s is powered %s' % (interface, powered))
            elif command == 'list' or command == '':
                print_properties(path, properties)
            else:
                print('Unknown command')

    else:
        print('Unknown command')


if __name__ == '__main__':
    main()
