#!/usr/bin/python3

import sys
from gi.repository import Gio, GLib

VERSION = '0.8.1'

def usage_main():
    print('Usage:')
    print('  powerprofilesctl COMMAND [ARGS…]')
    print('')
    print('Commands:')
    print('  help       Print help')
    print('  version    Print version')
    print('  get        Print the currently active power profile')
    print('  set        Set the currently active power profile')
    print('  list       List available power profiles')
    print('')
    print('Use “powerprofilesctl help COMMAND” to get detailed help.')

def usage_version():
    print('Usage:')
    print('  powerprofilesctl version')
    print('')
    print('Print version information and exit.')

def usage_get():
    print('Usage:')
    print('  powerprofilesctl get')
    print('')
    print('Print the currently active power profile.')

def usage_set():
    print('Usage:')
    print('  powerprofilesctl set PROFILE')
    print('')
    print('Set the currently active power profile. Must be one of the ')
    print('available profiles.')

def usage_list():
    print('Usage:')
    print('  powerprofilesctl list')
    print('')
    print('List available power profiles.')

def usage(_command=None):
    if not _command:
        usage_main()
    elif _command == 'get':
        usage_get()
    elif _command == 'set':
        usage_set()
    elif _command == 'list':
        usage_list()
    elif _command == 'version':
        usage_version()
    else:
        usage_main()

def version():
    print (VERSION)

def get_proxy():
    try:
        bus = Gio.bus_get_sync(Gio.BusType.SYSTEM, None)
        proxy = Gio.DBusProxy.new_sync(bus, Gio.DBusProxyFlags.NONE, None,
                                       'net.hadess.PowerProfiles',
                                       '/net/hadess/PowerProfiles',
                                       'org.freedesktop.DBus.Properties', None)
    except:
        raise SystemError
    return proxy

def _get():
    proxy = get_proxy()
    profile = proxy.Get('(ss)', 'net.hadess.PowerProfiles', 'ActiveProfile')
    print(profile)

def _set(profile):
    proxy = get_proxy()
    proxy.Set('(ssv)',
        'net.hadess.PowerProfiles',
        'ActiveProfile',
        GLib.Variant.new_string(profile))

def get_profiles_property(prop):
    try:
        proxy = get_proxy()
    except:
        raise SystemError

    profiles = None
    try:
        profiles = proxy.Get('(ss)', 'net.hadess.PowerProfiles', prop)
    except:
        raise ReferenceError
    else:
        return profiles

def _list():
    try:
        profiles = get_profiles_property('Profiles')
        reason = get_proxy().Get('(ss)', 'net.hadess.PowerProfiles', 'PerformanceInhibited')
        inhibited = (reason != '')
        active = get_proxy().Get('(ss)', 'net.hadess.PowerProfiles', 'ActiveProfile')
    except:
        print("Couldn\'t get Profiles: ", sys.exc_info()[0])
        raise SystemError
    else:
        index = 0
        for profile in reversed(profiles):
            if index > 0:
                print('')
            print(('%s %s:') % ('*' if profile['Profile'] == active else ' ', profile['Profile']))
            print('    Driver:    ', profile['Driver'])
            if profile['Profile'] == 'performance':
                print('    Inhibited: ', f'yes ({reason})' if inhibited else 'no')
            index += 1

def main(): # pylint: disable=too-many-branches
    args = None
    if len(sys.argv) == 1:
        command = 'list'
    elif len(sys.argv) >= 2:
        command = sys.argv[1]
        if command == '--help':
            command = 'help'
        if command == '--version':
            command = 'version'
        else:
            args = sys.argv[2:]

    if command == 'help':
        if len(args) > 0:
            usage(args[0])
        else:
            usage(None)
    elif command == 'version':
        version()
    elif command == 'get':
        _get()
    elif command == 'set':
        if len(args) != 1:
            usage_set()
            sys.exit(1)
        _set(args[0])
    elif command == 'list':
        _list()

if __name__ == '__main__':
    main()
