'''workspace.py - Display or create workspaces on remote server'''

import wx, paramiko
import paramiko_mods

from paramiko import AuthenticationException
import definedWxClasses, const

from foamGUI import FoamFrame

class WorkspaceWindow(wx.Dialog):
    '''Dialog window'''
    def __init__(self, loginInfo, *args, **kwargs):
        wx.Dialog.__init__(self, parent=None, id=-1, title="Workspaces", size=(500, 300))

        self.SetSizer(WsSizer(self, loginInfo))

class WsSizer(wx.BoxSizer):
    '''Sizer'''
    def __init__(self, parent, loginInfo, *args, **kwargs):
        wx.BoxSizer.__init__(self, wx.VERTICAL)
        stdout, stderr = paramiko_mods.exec_cluster_command('ws_list', **loginInfo)

        self.parent = parent
        self.loginInfo = loginInfo

        if stdout[3:] == []:
            '''if there are no active workspaces'''
            print 'No workspaces available!'
            tlabel = "No available workspaces found.\nCreate a new one:"
            #self.addTitle(parent, tlabel)

            '''Create new workspace Window'''
            self.createNewWS(parent, self, tlabel)
            return
        tlabel = "Choose a workspace on\n{}:".format(loginInfo['hostname'])
        self.addTitle(parent, self, tlabel)

        '''WORKSPACES'''
        ws_spaces = {}
        stdout = stdout[3:]
        while stdout != []:
            ws_name = stdout[0].split()[0]
            ws_path = stdout[1].strip()
            ws_spaces[ws_name] = ws_path
            stdout = stdout[4:]

        ws_choices = []
        for item in ws_spaces:
            ws_choices.append('{} --> {}'.format(item, ws_spaces[item]))
        ws_spaces_box = wx.RadioBox(parent, label="Available workspaces:",
            choices=ws_choices, style=wx.RA_VERTICAL, name="workspace")
        self.Add(ws_spaces_box, 0, wx.ALL|wx.EXPAND, 10)

        '''BUTTONS'''
        okBtn = wx.Button(parent, wx.ID_OK)
        cancelBtn = wx.Button(parent, wx.ID_CANCEL)
        newBtn = wx.Button(parent, wx.ID_NEW)
        deleteBtn = wx.Button(parent, wx.ID_DELETE)

        okBtn.SetDefault()

        okBtn.Bind(wx.EVT_BUTTON, self.okClick)
        newBtn.Bind(wx.EVT_BUTTON, self.newClick)
        deleteBtn.Bind(wx.EVT_BUTTON, self.deleteClick)
        cancelBtn.Bind(wx.EVT_BUTTON, self.onClose)

        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        btnSizer.AddMany([okBtn, const.hbtnSpace, newBtn, const.hbtnSpace,
            deleteBtn, const.hbtnSpace, cancelBtn])
        self.Add(btnSizer, 0, wx.ALL|wx.ALIGN_RIGHT|wx.EXPAND, 10)


    def onClose(self, event):
        '''close application'''
        self.parent.Destroy()

    def wsChoice(self, parent):
        '''return the chosen value from ws checkboxes'''
        selection = parent.FindWindowByName('workspace').GetStringSelection().split()
        selection.remove('-->')
        return selection

    def deleteClick(self, evt):
        '''delete a workspace btn click'''
        chosen = self.wsChoice(self.parent)
        msg = "Are you sure you want to remove {} with path {}?".format(chosen[0], chosen[1])
        dlg = wx.MessageDialog(self.parent, message=msg, style=wx.YES_NO|wx.YES_DEFAULT)
        if dlg.ShowModal() == wx.ID_YES:
            cmd = "ws_release {}".format(chosen[0])
            print cmd
            paramiko_mods.exec_cluster_command(cmd, **self.loginInfo)
            self.parent.Close()

    def newClick(self, evt):
        '''create a new workspace button click'''
        title = "Create a new workspace:"
        dlg = wx.Dialog(None, title="Create a new workspace")
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.createNewWS(dlg, sizer, title)
        dlg.SetSizer(sizer)
        dlg.ShowModal()

    def okClick(self, evt):
        '''select the available workspace and click 'Ok' '''
        selection = self.wsChoice(self.parent)
        self.loginInfo['remotePath'] = selection[1]
        FoamFrame(parent=None, remoteData=self.loginInfo).Show()
        self.parent.Close()

    def addTitle(self, parent, sizer, tlabel):
        '''Add title string to your sizer'''
        title = definedWxClasses.SectionTitleSizer(parent, tlabel,
            size=(450, -1), hline=False)
        sizer.Add(title, 0, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL, 10)

    def createNewWS(self, parent, sizer, title):
        """create new workspace sizer"""

        """TITLE"""
        self.addTitle(parent, sizer, title)

        '''BOXES'''
        sizer.AddMany([
            self.boxesSizer(parent, "Workspace Name:", 'wsname'), #wsname
            self.boxesSizer(parent, "Duration in days (max. 60):", 'wsdur')
        ])

        '''BUTTONS'''
        okBtn = wx.Button(parent, wx.ID_OK)
        cancelBtn = wx.Button(parent, wx.ID_CANCEL)
        okBtn.Bind(wx.EVT_BUTTON, self.newOkClick)
        okBtn.SetDefault()
        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        btnSizer.AddMany([okBtn, const.hbtnSpace, cancelBtn])
        sizer.AddMany([(-1, 20), (btnSizer, 0, wx.ALIGN_RIGHT|wx.ALL, 20)])

        self.newParent = parent

    def boxesSizer(self, parent, label, name, size_label=(250, -1), size_box=(200,-1)):
        '''Sizer for text boxes'''
        boxesSizer = wx.BoxSizer(wx.HORIZONTAL)
        boxesSizer.AddMany([
            (definedWxClasses.LabelFormat(parent, label=label, size=size_label), 0, wx.ALL, 10),
            (wx.TextCtrl(parent, -1, name=name, size=size_box), 0, wx.ALL, 5)
        ])
        return boxesSizer

    def newOkClick(self, evt):
        wsname = wx.FindWindowByName('wsname').GetValue()
        wsdur = wx.FindWindowByName('wsdur').GetValue()
        try:
            if int(wsdur) > 60 or int(wsdur) < 0: wsdur = 60
        except ValueError:
            wsdur = 60
        if wsname != '':
            cmd = 'ws_allocate {} {}'.format(wsname, wsdur)
            print cmd
            stdout, stderr = paramiko_mods.exec_cluster_command(cmd, **self.loginInfo)
            print stdout
            self.newParent.Close()
            self.parent.Close()
        print [wsname, wsdur]
        self.loginInfo['remotePath'] = stdout[0].replace('\n', '')
        FoamFrame(parent=None, remoteData=self.loginInfo).Show()

class CreateNewWsSizer(wx.BoxSizer):
    '''create a new workspace sizer'''
    def __init__(self, parent, *args, **kwargs):
        wx.BoxSizer.__init__(self, wx.HORIZONTAL)


if __name__ == "__main__":
    from remote_data import loginInfo
    app = wx.App(False)
    WorkspaceWindow(loginInfo).Show()
    app.MainLoop()
