#!/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 pprint
import sys

import common
from autotest_lib.client.cros.networking import shill_proxy

def usage():
    """ Prints a script usage message. """
    cmd = sys.argv[0]
    print 'Usage: %s <command> [more parameters]' % cmd
    print 'Example uses:'
    print cmd, 'create <name> - Create a profile called |name|.'
    print cmd, 'push <name> - Push a previously created profile called |name|.'
    print cmd, 'pop <name> - Pop a profile called |name|.'
    print cmd, 'pop - Pop the top-most profile.'
    print cmd, 'remove <name> - Remove a profile called |name| from disk.'
    print cmd, 'clean - Pop and remove profiles above the default profile.'
    print cmd, 'list - List profiles and their properties.'
    print cmd, 'list-entries - List profile entries.'
    print cmd, 'delete-entry <entry> [name] - Delete an entry from a ' \
        'profile called |name| or all profiles if no name is given.'
    return False


def print_profile_path(profile_path, active_path):
    """ Print profile_path and indicate if it is the active profile. """
    if profile_path == active_path:
        print 'Profile: %s  <== active' % profile_path
    else:
        print 'Profile: %s' % profile_path


def clean_profiles():
    """ Pop and remove all profiles until 'default' is found. """
    shill = shill_proxy.ShillProxy()
    while True:
        active_profile = shill.get_active_profile()
        properties = active_profile.GetProperties(utf8_strings=True)
        active_name = shill.dbus2primitive(
                properties[shill.PROFILE_PROPERTY_NAME])
        if active_name == 'default':
            return True
        else:
            print 'Removing profile: %s' % active_name
            shill.manager.PopProfile(active_name)
            shill.manager.RemoveProfile(active_name)


def delete_entry():
    """
    Remove an entry from the specified profile, or all profiles if no profile
    is given.

    """
    if len(sys.argv) <= 2:
        return usage()
    identifier = sys.argv[2]
    profile_path = None
    if len(sys.argv) > 3:
      profile_path = sys.argv[3]
    shill = shill_proxy.ShillProxy()
    properties = shill.dbus2primitive(
        shill.manager.GetProperties(utf8_strings=True))
    active_profile = shill.get_active_profile()
    for path in properties[shill.MANAGER_PROPERTY_PROFILES]:
        print_profile_path(path, active_profile.object_path)
        if profile_path and path != profile_path:
            continue

        profile = shill.get_dbus_object(shill.DBUS_TYPE_PROFILE, path)
        try:
            profile.DeleteEntry(identifier)
            print " -> delete succeeded"
        except:
            print " -> delete failed"


def list_entries():
    """ Display detailed profile entry information. """
    shill = shill_proxy.ShillProxy()
    active_profile = shill.get_active_profile()
    for profile in shill.get_profiles():
        print_profile_path(profile.object_path, active_profile.object_path)
        properties = shill.dbus2primitive(
                profile.GetProperties(utf8_strings=True))
        if not shill.PROFILE_PROPERTY_ENTRIES in properties:
            continue
        for ident in properties[shill.PROFILE_PROPERTY_ENTRIES]:
            print 'Entry: %s' % ident
            pprint.pprint(shill.dbus2primitive(profile.GetEntry(ident)),
                          indent=2)
        print
    return True


def list_profiles():
    """ List shill profiles and their properties. """
    shill = shill_proxy.ShillProxy()
    active_profile = shill.get_active_profile()
    for profile in shill.get_profiles():
        print_profile_path(profile.object_path, active_profile.object_path)
        properties = shill.dbus2primitive(
                profile.GetProperties(utf8_strings=True))
        pprint.pprint(properties, indent=2)
        print
    return True


def main():
    """ Main entry point for the profile script. """
    if len(sys.argv) < 2:
        return usage()

    command = sys.argv[1]
    shill = shill_proxy.ShillProxy()

    if command == 'clean':
        return clean_profiles()

    if command == 'delete-entry':
        return delete_entry()

    if command == 'list':
      return list_profiles()

    if command == 'list-entries':
        return list_entries()

    if command == 'pop' and len(sys.argv) == 2:
        shill.manager.PopAnyProfile()
        print 'Popped profile.'
        return True

    # All the remaining operations require a profile name.
    if len(sys.argv) < 3:
        return usage()

    name = sys.argv[2]

    if command == 'pop':
        shill.manager.PopProfile(name)
        print 'Popped profile %s.' % name
        return True

    if command == 'create':
        path = shill.manager.CreateProfile(name)
        print 'New profile created at %s.' % path
        return True

    if command == 'push':
        path = shill.manager.PushProfile(name)
        print 'Pushed profile %s.' % path
        return True

    if command == 'remove':
        shill.manager.RemoveProfile(name)
        print 'Removed profile %s.' % name
        return True

    return usage()


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