#!/usr/pythoncontroller/python

import sys
import onappstoreAPI
from netlib import *
from redislib import *
from util import *

supported = ["list","listlocal","listdatastores","createdatastore","create","delete","activate","deactivate",\
                 "addNodetoDatastore","removeNodefromDatastore","snapshot","onlineDisk","offlineDisk","nodes", "diskinfo", \
                 "nodeinfo"]

def help():
    print "Usage: onappstore <ARG>"
    print "\thelp - print this info"
    print "\tlist - output the current vdisk image library"
    print "\tlistlocal - output the current vdisk images stored locally"
    print "\tlistdatastores - output the current datastore library"
    print "\tcreatedatastore name=<NAME> membership_count=<# of disks> [desc=<DESCRIPTION>] [uuid=<DS UUID>] [replicas=<NO OF REPLICAS>] [stripes=<NO OF STRIPES>] [sector_size=<sector size>] [owners=<comma separated list of node uuids to host this ds on (must be equal to membership_count)>]"
    print "\taddNodetoDatastore uuid=<DS UUID> member_uuid=<NODE UUID>"
    print "\tremoveNodefromDatastore uuid=<DS UUID> member_uuid=<NODE UUID>"
    print "\tcreate name=<NAME> size=<SIZE (MB)> datastore=<DS UUID> [desc=<DESCRIPTION>] [stripesize=<stripesize in KB>]"
    print "\tactivate uuid=<UUID> - activate a vdisk on all owning nodes"
    print "\tdeactivate uuid=<UUID> - deactivate a vdisk on all owning nodes"
    print "\tonlineDisk uuid=<UUID> ipaddr=<HEADEND_IP>"
    print "\tofflineDisk uuid=<UUID>"
    print "\tsnapshot uuid=<UUID> - snapshot a vdisk"
    print "\tdelete uuid=<UUID> [member_uuid=<uuid for the member to delete this vdisk from>] - delete a vdisk"
    print "\tdiskinfo uuid=<UUID> - get relevant information about a vdisk"
    print "\tnodeinfo uuid=<UUID> - get relevant information about a node"
    #print "\trollback <NAME> <EPOCH> - rollback a vdisk to a given snap epoch"
    print "\tnodes - list active node members, optional minimal=true, showips=true"
    sys.exit()

def parse(listOfArgs):
    args = {}
    index = 0
    for arg in listOfArgs:
        # ignore the first 2 parameters
        index += 1
        if index < 2:
	    continue
        if arg.find('=') != -1:
            args[arg.split('=')[0]] = arg.split('=')[1]
    return args

def ensureRequiredParamsPresent(dict, required_keys):
    for key in required_keys:
        if not dict.has_key(key):
            help()
            sys.exit()

def displayVDisks(vdisks):
    for key in vdisks.iterkeys():
        entry = vdisks[key]
        if entry["status"] == INACTIVE:
            status = "INACTIVE"
        else:
            status = "ACTIVE"
        size = int(entry["sectors"]) * int(entry["sector_size"])
        print "Node [%s]" % key
        print "     Name:        %s" % entry["name"]
        print "     Status:      %s" % status
        print "     Size:        %d MB" % (size/(1024*1024))
        print "     Sector-size: %d Bytes" % entry["sector_size"]
        print "     Requested replicas: %d " % entry["replicas"]
        print "     Stripe Members: %d " % entry["st_mems"]
        print "     Stripe size: %dK " % entry["st_size"]
        print "     Utilisation: %d%%" % ((entry["numkeys"]/entry["sectors"])*100)
        print "     Description: %s" % entry["description"]
        if len(entry["snapshots"]):
            print "     Snapshots: %s" % entry["snapshots"]
        print "\n"
    
if len(sys.argv) < 2:
    help()

if not sys.argv[1] in supported:
    help()

initEnvars()

# if there are arguments parse them into a dictionary
args = parse(sys.argv)

# commands which do not return name-value pairs
if sys.argv[1] == "list":
    vdisks = onappstoreAPI.getVDiskInfo({})
    displayVDisks(vdisks) 
    sys.exit()
 
if sys.argv[1] == "listlocal":
    nodeid = getNodeId()
    vdisks = onappstoreAPI.getVDiskInfo({})
    localvdisks = vdisks.copy()
    for vdisk in vdisks:
        if nodeid not in set(vdisks[vdisk]['members'].split(',')):
            del localvdisks[vdisk]
    displayVDisks(localvdisks)
    sys.exit()
 
if sys.argv[1] == "listdatastores":
    ds = onappstoreAPI.getDatastoreInfo({})
    for key in ds.iterkeys():
        entry = ds[key]
        if entry["provisioning"] == THIN:
            prov = "THIN"
        else:
            prov = "THICK"
        print "Datastore [%s]" % key
        print "     Name:           %s" % entry["name"]
        print "     Description:    %s" % entry["description"]
        print "     Sector-size:    %s Bytes" % entry["sector_size"]
        print "     VDisk replicas: %s " % entry["replicas"]
        print "     VDisk stripes:  %s " % entry["stripes"]
        print "     Provisioning:   %s" % prov
        print "     Members:        %s" % entry["members"]
        print "\n"
    sys.exit()

# commands which do return name-value pairs
retVal = 'result='
try:
    if sys.argv[1] == "createdatastore":
	ensureRequiredParamsPresent(args, ['name', 'membership_count'])
	ret = dictToString(onappstoreAPI.createDatastore(args),pairsplitter='=',separator=' ')
        retVal += 'SUCCESS %s' % ret  
    elif sys.argv[1] == "addNodetoDatastore":
	ensureRequiredParamsPresent(args, ['uuid', 'member_uuid'])
	ret = dictToString(onappstoreAPI.nodeaddDatastore(args),pairsplitter='=',separator=' ')
        retVal += 'SUCCESS %s' % ret  
    elif sys.argv[1] == "removeNodefromDatastore":
	ensureRequiredParamsPresent(args, ['uuid', 'member_uuid'])
	ret = dictToString(onappstoreAPI.noderemoveDatastore(args),pairsplitter='=',separator=' ')
        retVal += 'SUCCESS %s' % ret  
    elif sys.argv[1] == "create":
	ensureRequiredParamsPresent(args, ['name', 'size', 'datastore'])
	ret = dictToString(onappstoreAPI.createVDisk(args),pairsplitter='=',separator=' ')
        retVal += 'SUCCESS %s' % ret  
    elif sys.argv[1] == "delete":
	ensureRequiredParamsPresent(args, ['uuid'])
	ret = dictToString(onappstoreAPI.deleteVDisk(args),pairsplitter='=',separator=' ')
        retVal += 'SUCCESS %s' % ret  
    elif sys.argv[1] == "diskinfo":
	ensureRequiredParamsPresent(args, ['uuid'])
        info = onappstoreAPI.getVDiskInfo({})[args['uuid']]
	copy = info.copy()
        dictVal = ' '
        for key in info.iterkeys():
	    if type(info[key]) is dict:
		val = '%s' % info[key]
		val = val.strip('{').strip('}').replace('\'','').replace(' ','')
		dictVal += '%s=%s' % (key, val)
	        dictVal += ' '
                del copy[key]
            
	dictVal = dictVal.rstrip()
	ret = dictToString(copy, pairsplitter='=',separator=' ') + dictVal
        retVal += 'SUCCESS %s' % ret  
    elif sys.argv[1] == "nodeinfo":
	ensureRequiredParamsPresent(args, ['uuid'])
	ret = onappstoreAPI.getNodeInfo({'uuid':args['uuid']})
        retVal += 'SUCCESS %s' % ret  
    #elif sys.argv[1] == "snapshot":
    #    ensureRequiredParamsPresent(args, ['uuid'])
    #    print snapshot(args['uuid'])
    #elif sys.argv[1] == "revert":
    #    dbrevert(sys.argv[2], sys.argv[3])
    elif sys.argv[1] == "activate":
	ensureRequiredParamsPresent(args, ['uuid'])
	ret = dictToString(onappstoreAPI.activateVDisk(args),pairsplitter='=',separator=' ')
        retVal += 'SUCCESS %s' % ret  
    elif sys.argv[1] == "deactivate":
	ensureRequiredParamsPresent(args, ['uuid'])
	ret = dictToString(onappstoreAPI.deactivateVDisk(args),pairsplitter='=',separator=' ')
        retVal += 'SUCCESS %s' % ret  
    elif sys.argv[1] == "onlineDisk":
	ensureRequiredParamsPresent(args, ['uuid','ipaddr'])
	ret = dictToString(onappstoreAPI.onlineVDisk(args),pairsplitter='=',separator=' ')
        retVal += 'SUCCESS %s' % ret  
    elif sys.argv[1] == "offlineDisk":
	ensureRequiredParamsPresent(args, ['uuid'])
	ret = dictToString(onappstoreAPI.offlineVDisk(args),pairsplitter='=',separator=' ')
        retVal += 'SUCCESS %s' % ret  
    elif sys.argv[1] == "nodes":
	minimal = False
	showips = False
	nodes = onappstoreAPI.getNodeInfo({})
	if args.has_key('minimal') and args['minimal'] == 'true':
	    minimal = True   
	if args.has_key('showips') and args['showips'] == 'true':
	    showips = True
        if not minimal and not showips:
            for node in nodes:
		entry = nodes[node]
		if entry['status'] == INACTIVE:
		    status = "INACTIVE"
		else:
		    status = "ACTIVE"
		print "Node: %s" % node
		print "\tstatus: %s" % status
		print "\tIP addr: %s" % entry['ipaddr']
		if entry['storagestatus'] == FRONTEND_STORAGENODE:
		    print "\tRole: FRONTEND node"
		else:
		    print "\tRole: BACKEND node"
		print "\n"
            sys.exit()
        if minimal:
            retVal += 'SUCCESS nodes='
            for node in nodes: 
                if showips:
                    retVal += nodes[node]['ipaddr']
                    retVal += ','
                else:
                    retVal += node
                    retVal += ','
            retVal = retVal.strip(',')  
except Exception, e:
    retVal += 'FAILURE Error=%s' % str(e)

print retVal 
