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