#!/usr/bin/python

from diskutil import *
from snack import *


screen = SnackScreen()
bb = ButtonBar(screen, (("Select", "ok"), ("Exit", "cancel")))
subb = ButtonBar(screen, (("Ok", "ok"), ("Back", "cancel")))
singleb = Button("Ok")


def mainMenu():
    conf = parseCurrentConfig()
    li = Listbox(height = 9, width = 60, returnExit = 1)
    li.append("Enable or Disable storage Service", 1)
    li.append("Display Current Config", 2)
    li.append("Add Disk", 3)
    li.append("Remove Disk", 4)
    #Storage service must be disabled to change host ID
    #and for any network config changes 
    if conf['enabled'] == 0:
        li.append("Set Host ID", 7)
        if conf['hostid'] > 0:
            li.append("Create NIC bond", 8)
            li.append("Disable NIC bond", 9)
            li.append("Add SAN Network Interface", 5)
            li.append("Remove SAN Network Interface", 6)

    g = GridForm(screen, "OnappStore Configurator", 1, 2)
    g.add(li, 0, 0, (1, 1, 1, 1))
    g.add(bb, 0, 1, growx = 1)

    result = g.runOnce()
    if bb.buttonPressed(result) == 'cancel':
        return 0
    return li.current()

def DisplayCurrent():
    conf = parseCurrentConfig()
    text = "Current Host Config:\n"
    if conf['enabled'] == 1:
        text += "\tstatus:      ENABLED\n"
    else:
        text += "\tstatus:      DISABLED\n"
    if conf['hostid'] == 0:
        text += "\thost ID:     NOT SET\n"
    else:
        text += "\thost ID:     %d\n" % conf['hostid']
    if len(conf['interfaces']):
        text += "\tbridge:      ATTACHED %s\n" % str(conf['interfaces'])
    else:
        text += "\tbridge:      DETACHED\n"
    assigned = diskAssignment(True)
    unassigned = diskAssignment(False)
    mounted = getMountdevs()
    unassigned = set(mounted) ^ set(unassigned)

    if len(assigned):
        text += "Active Disk Assignment:\n"
        for dev in assigned:
            text += "\t%s\n" % dev
        
    if len(unassigned):
        text += "Unassigned Disks:\n"
        for dev in unassigned:
            text += "\t%s\n" % dev

    if len(text.split('\n'))-1 > 10:
        sc = 1
    else:
        sc = 0

    tb = Textbox(40, 10, text,scroll=sc,wrap=1)
    g = GridForm(screen, "Current Configuration", 1, 2)
    g.add(tb, 0, 0)
    g.add(singleb, 0, 1, growx = 1) 
    result = g.runOnce()
    return
    
def EnableDisableMenu():
    rb = RadioBar(screen, (("Enabled", "enabled", 0),
                           ("Disabled", "disabled", 1)))

    tb = Textbox(40, 3, "Operation not permitted: You must set the Host ID first",wrap=1)

    g = GridForm(screen, "OnappStore Configurator", 1, 2)
    g.add(rb, 0, 0)
    g.add(subb, 0, 1, growx = 1)
    result = g.runOnce()
    if subb.buttonPressed(result) == 'cancel':
        return
    if rb.getSelection() == 'enabled':
        if getHostID() == 0:
            g = GridForm(screen, "Operation Not Permitted", 1, 2)
            g.add(tb, 0, 0)
            g.add(singleb, 0, 1, growx = 1) 
            result = g.runOnce()
            return
        EnableHost()
    else:
        DisableHost()
    return

def AddInterface():
    unassigned = AssignedInterfaces(False)
    if not len(unassigned):
        tb = Textbox(40,1,"No interfaces Available to Assign")
        g = GridForm(screen, "Onappstore Interface Add wizard", 1, 2)
        g.add(tb, 0, 0, (10, 1, 10, 1))
        g.add(singleb, 0, 1, growx = 1)
        result = g.runOnce()
        return

    sc = 0
    if len(unassigned) > 4:
        sc = 1
    ct = CheckboxTree(height = 5, scroll = sc)
    for dev in unassigned:
        ct.append(dev, selected=0)
    g = GridForm(screen, "Onappstore Add Interface to Bridge wizard", 1, 2)
    g.add(ct, 0, 0, (10, 1, 10, 1))
    g.add(subb, 0, 1, growx = 1)
    result = g.runOnce()

    if subb.buttonPressed(result) == 'cancel':
        return
    newdevs = ct.getSelection()
    for dev in newdevs:
        assignInterfacetoBridge(dev)
    return

def RemoveInterface():
    currentconf = parseCurrentConfig()
    assigned = currentconf['interfaces']
    #assigned = AssignedInterfaces(True)
    if not len(assigned):
        tb = Textbox(40,1,"No interfaces Available to Unassign")
        g = GridForm(screen, "Onappstore Interface Release wizard", 1, 2)
        g.add(tb, 0, 0, (10, 1, 10, 1))
        g.add(singleb, 0, 1, growx = 1)
        result = g.runOnce()
        return

    sc = 0
    if len(assigned) > 4:
        sc = 1
    ct = CheckboxTree(height = 5, scroll = sc)
    for dev in assigned:
        ct.append(dev, selected=0)
    g = GridForm(screen, "Onappstore Remove Interface from Bridge wizard", 1, 2)
    g.add(ct, 0, 0, (10, 1, 10, 1))
    g.add(subb, 0, 1, growx = 1)
    result = g.runOnce()

    if subb.buttonPressed(result) == 'cancel':
        return
    newdevs = ct.getSelection()
    for dev in newdevs:
        removeInterfacefromBridge(dev)
    return

def addBondIntf():
    bonds = listBondNodes()
    createBondDev()
    unassigned = AssignedInterfaces(False)
    if not len(unassigned):
        tb = Textbox(40,1,"No interfaces Available to Assign to Bond")
        g = GridForm(screen, "Onappstore Bond Interface Add wizard", 1, 2)
        g.add(tb, 0, 0, (10, 1, 10, 1))
        g.add(singleb, 0, 1, growx = 1)
        result = g.runOnce()
        return

    sc = 0
    if len(unassigned) > 4:
        sc = 1
    ct = CheckboxTree(height = 5, scroll = sc)
    for dev in unassigned:
        ct.append(dev, selected=0)
    g = GridForm(screen, "Onappstore Add Interface to Bond wizard", 1, 2)
    g.add(ct, 0, 0, (10, 1, 10, 1))
    g.add(subb, 0, 1, growx = 1)
    result = g.runOnce()

    if subb.buttonPressed(result) == 'cancel':
        return
    newdevs = ct.getSelection()
    for dev in newdevs:
        configBondSlave(dev, True)
    return    

def removeBondIntf():
    bonds = listBondNodes()
    if not bonds.has_key('onappstorebond'):
        assigned = []
    else:
        assigned = bonds['onappstorebond']
    if not len(assigned):
        tb = Textbox(40,1,"No interfaces Available to Unassign")
        g = GridForm(screen, "Onappstore Bond Slave Release wizard", 1, 2)
        g.add(tb, 0, 0, (10, 1, 10, 1))
        g.add(singleb, 0, 1, growx = 1)
        result = g.runOnce()
        return

    sc = 0
    if len(assigned) > 4:
        sc = 1
    ct = CheckboxTree(height = 5, scroll = sc)
    for dev in assigned:
        ct.append(dev, selected=0)
    g = GridForm(screen, "Onappstore Remove slave Interface from Bond wizard [Requires reboot]", 1, 2)
    g.add(ct, 0, 0, (10, 1, 10, 1))
    g.add(subb, 0, 1, growx = 1)
    result = g.runOnce()

    if subb.buttonPressed(result) == 'cancel':
        return
    newdevs = ct.getSelection()
    for dev in newdevs:
        configBondSlave(dev,False)
    return

def AddDisk():
    unassigned = diskAssignment(False)
    mounted = getMountdevs()

    unassigned = set(mounted) ^ set(unassigned)
    if not len(unassigned):
        tb = Textbox(40,1,"No disks Available to Assign")
        g = GridForm(screen, "Onappstore Disk add wizard", 1, 2)
        g.add(tb, 0, 0, (10, 1, 10, 1))
        g.add(singleb, 0, 1, growx = 1)
        result = g.runOnce()
        return

    sc = 0
    if len(unassigned) > 4:
        sc = 1
    ct = CheckboxTree(height = 5, scroll = sc)
    for dev in unassigned:
        ct.append(dev, selected=0)
    cb = Checkbox("Format Disks [WARNING: all data on disk will be lost!]",isOn=0)
    g = GridForm(screen, "Onappstore Disk add wizard", 1, 3)
    g.add(ct, 0, 0, (10, 1, 10, 1))
    g.add(cb, 0, 1, (10, 1, 10, 1))
    g.add(subb, 0, 2, growx = 1)
    result = g.runOnce()

    if subb.buttonPressed(result) == 'cancel':
        return
    newdevs = ct.getSelection()
    conf = parseCurrentConfig()
    enabled = (conf['enabled'] == 1)
    for dev in newdevs:
        if cb.value() == 1:
            formatDisk(dev)
        addDisktoConfig(dev)
        if enabled:
            createDevVMConfig(dev)
            startNode(dev)
    return

def RemoveDisk():
    assigned = diskAssignment(True)
    if not len(assigned):
        tb = Textbox(40,1,"No disks Currently Assigned")
        g = GridForm(screen, "Onappstore Disk remove wizard", 1, 2)
        g.add(tb, 0, 0, (10, 1, 10, 1))
        g.add(singleb, 0, 1, growx = 1)
        result = g.runOnce()
        return

    sc = 0
    if len(assigned) > 4:
        sc = 1
    ct = CheckboxTree(height = 5, scroll = sc)
    for dev in assigned:
        ct.append(dev, selected=0)
    cb = Checkbox("Zero disk contents [WARNING: all data on disk will be lost!]",isOn=0)
    g = GridForm(screen, "Onappstore Disk remove wizard", 1, 3)
    g.add(ct, 0, 0, (10, 1, 10, 1))
    g.add(cb, 0, 1, (10, 1, 10, 1))
    g.add(subb, 0, 2, growx = 1)
    result = g.runOnce()

    if subb.buttonPressed(result) == 'cancel':
        return
    newdevs = ct.getSelection()
    for dev in newdevs:
        stopNode(dev)
        removeDiskfromConfig(dev)
        removeDevVMConfig(dev)
        if cb.value() == 1:
            unformatDisk(dev)
    return

def SetHostID():
    e = EntryWindow(screen,"Enter Host ID","",["ID"],width=15,buttons=['Ok','Return'])
    print e
    if e[0] == 'ok':
        try:
            arr = e[1]
            hostID = int(arr[0])
            setHostID(hostID)
        except ValueError:
            tb = Textbox(40, 3, "Inavlid Host ID: Must be an integer between 1 and 255",wrap=1)
            g = GridForm(screen, "Invalid Host ID", 1, 2)
            g.add(tb, 0, 0)
            g.add(singleb, 0, 1, growx = 1) 
            result = g.runOnce()
            return

    return


run = True
while run:
    res = mainMenu()
    if res == 1:
        EnableDisableMenu()
    elif res == 2:
        DisplayCurrent()
    elif res == 3:
        AddDisk()
    elif res == 4:
        RemoveDisk()
    elif res == 5:
        AddInterface()
    elif res == 6:
        RemoveInterface()
    elif res == 7:
        SetHostID()
    elif res == 8:
        addBondIntf()
    elif res == 9:
        removeBondIntf()
    else:
        run = False

screen.finish()

#print "rb:", rb.getSelection()
#for dev in devs.iterkeys():
#    print "%s:" % dev, ct.getEntryValue(dev)
#print "cb:", cb.value()
#print "bb:", bb.buttonPressed(result)

