#!/usr/bin/env python
#
# Autogenerated by Thrift Compiler (0.18.1)
#
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
#
#  options string: py
#

import sys
import pprint
if sys.version_info[0] > 2:
    from urllib.parse import urlparse
else:
    from urlparse import urlparse
from thrift.transport import TTransport, TSocket, TSSLSocket, THttpClient
from thrift.protocol.TBinaryProtocol import TBinaryProtocol

from airavata.service.profile.groupmanager.cpi import GroupManagerService
from airavata.service.profile.groupmanager.cpi.ttypes import *

if len(sys.argv) <= 1 or sys.argv[1] == '--help':
    print('')
    print('Usage: ' + sys.argv[0] + ' [-h host[:port]] [-u url] [-f[ramed]] [-s[sl]] [-novalidate] [-ca_certs certs] [-keyfile keyfile] [-certfile certfile] function [arg1 [arg2...]]')
    print('')
    print('Functions:')
    print('  string createGroup(AuthzToken authzToken, GroupModel groupModel)')
    print('  bool updateGroup(AuthzToken authzToken, GroupModel groupModel)')
    print('  bool deleteGroup(AuthzToken authzToken, string groupId, string ownerId)')
    print('  GroupModel getGroup(AuthzToken authzToken, string groupId)')
    print('   getGroups(AuthzToken authzToken)')
    print('   getAllGroupsUserBelongs(AuthzToken authzToken, string userName)')
    print('  bool addUsersToGroup(AuthzToken authzToken,  userIds, string groupId)')
    print('  bool removeUsersFromGroup(AuthzToken authzToken,  userIds, string groupId)')
    print('  bool transferGroupOwnership(AuthzToken authzToken, string groupId, string newOwnerId)')
    print('  bool addGroupAdmins(AuthzToken authzToken, string groupId,  adminIds)')
    print('  bool removeGroupAdmins(AuthzToken authzToken, string groupId,  adminIds)')
    print('  bool hasAdminAccess(AuthzToken authzToken, string groupId, string adminId)')
    print('  bool hasOwnerAccess(AuthzToken authzToken, string groupId, string ownerId)')
    print('  string getAPIVersion()')
    print('')
    sys.exit(0)

pp = pprint.PrettyPrinter(indent=2)
host = 'localhost'
port = 9090
uri = ''
framed = False
ssl = False
validate = True
ca_certs = None
keyfile = None
certfile = None
http = False
argi = 1

if sys.argv[argi] == '-h':
    parts = sys.argv[argi + 1].split(':')
    host = parts[0]
    if len(parts) > 1:
        port = int(parts[1])
    argi += 2

if sys.argv[argi] == '-u':
    url = urlparse(sys.argv[argi + 1])
    parts = url[1].split(':')
    host = parts[0]
    if len(parts) > 1:
        port = int(parts[1])
    else:
        port = 80
    uri = url[2]
    if url[4]:
        uri += '?%s' % url[4]
    http = True
    argi += 2

if sys.argv[argi] == '-f' or sys.argv[argi] == '-framed':
    framed = True
    argi += 1

if sys.argv[argi] == '-s' or sys.argv[argi] == '-ssl':
    ssl = True
    argi += 1

if sys.argv[argi] == '-novalidate':
    validate = False
    argi += 1

if sys.argv[argi] == '-ca_certs':
    ca_certs = sys.argv[argi+1]
    argi += 2

if sys.argv[argi] == '-keyfile':
    keyfile = sys.argv[argi+1]
    argi += 2

if sys.argv[argi] == '-certfile':
    certfile = sys.argv[argi+1]
    argi += 2

cmd = sys.argv[argi]
args = sys.argv[argi + 1:]

if http:
    transport = THttpClient.THttpClient(host, port, uri)
else:
    if ssl:
        socket = TSSLSocket.TSSLSocket(host, port, validate=validate, ca_certs=ca_certs, keyfile=keyfile, certfile=certfile)
    else:
        socket = TSocket.TSocket(host, port)
    if framed:
        transport = TTransport.TFramedTransport(socket)
    else:
        transport = TTransport.TBufferedTransport(socket)
protocol = TBinaryProtocol(transport)
client = GroupManagerService.Client(protocol)
transport.open()

if cmd == 'createGroup':
    if len(args) != 2:
        print('createGroup requires 2 args')
        sys.exit(1)
    pp.pprint(client.createGroup(eval(args[0]), eval(args[1]),))

elif cmd == 'updateGroup':
    if len(args) != 2:
        print('updateGroup requires 2 args')
        sys.exit(1)
    pp.pprint(client.updateGroup(eval(args[0]), eval(args[1]),))

elif cmd == 'deleteGroup':
    if len(args) != 3:
        print('deleteGroup requires 3 args')
        sys.exit(1)
    pp.pprint(client.deleteGroup(eval(args[0]), args[1], args[2],))

elif cmd == 'getGroup':
    if len(args) != 2:
        print('getGroup requires 2 args')
        sys.exit(1)
    pp.pprint(client.getGroup(eval(args[0]), args[1],))

elif cmd == 'getGroups':
    if len(args) != 1:
        print('getGroups requires 1 args')
        sys.exit(1)
    pp.pprint(client.getGroups(eval(args[0]),))

elif cmd == 'getAllGroupsUserBelongs':
    if len(args) != 2:
        print('getAllGroupsUserBelongs requires 2 args')
        sys.exit(1)
    pp.pprint(client.getAllGroupsUserBelongs(eval(args[0]), args[1],))

elif cmd == 'addUsersToGroup':
    if len(args) != 3:
        print('addUsersToGroup requires 3 args')
        sys.exit(1)
    pp.pprint(client.addUsersToGroup(eval(args[0]), eval(args[1]), args[2],))

elif cmd == 'removeUsersFromGroup':
    if len(args) != 3:
        print('removeUsersFromGroup requires 3 args')
        sys.exit(1)
    pp.pprint(client.removeUsersFromGroup(eval(args[0]), eval(args[1]), args[2],))

elif cmd == 'transferGroupOwnership':
    if len(args) != 3:
        print('transferGroupOwnership requires 3 args')
        sys.exit(1)
    pp.pprint(client.transferGroupOwnership(eval(args[0]), args[1], args[2],))

elif cmd == 'addGroupAdmins':
    if len(args) != 3:
        print('addGroupAdmins requires 3 args')
        sys.exit(1)
    pp.pprint(client.addGroupAdmins(eval(args[0]), args[1], eval(args[2]),))

elif cmd == 'removeGroupAdmins':
    if len(args) != 3:
        print('removeGroupAdmins requires 3 args')
        sys.exit(1)
    pp.pprint(client.removeGroupAdmins(eval(args[0]), args[1], eval(args[2]),))

elif cmd == 'hasAdminAccess':
    if len(args) != 3:
        print('hasAdminAccess requires 3 args')
        sys.exit(1)
    pp.pprint(client.hasAdminAccess(eval(args[0]), args[1], args[2],))

elif cmd == 'hasOwnerAccess':
    if len(args) != 3:
        print('hasOwnerAccess requires 3 args')
        sys.exit(1)
    pp.pprint(client.hasOwnerAccess(eval(args[0]), args[1], args[2],))

elif cmd == 'getAPIVersion':
    if len(args) != 0:
        print('getAPIVersion requires 0 args')
        sys.exit(1)
    pp.pprint(client.getAPIVersion())

else:
    print('Unrecognized method %s' % cmd)
    sys.exit(1)

transport.close()
