import logging
from json import write
from ServerUtil import validateGroup

def getMenuJsonString(session):
        return write(MenuJson(session).getJson())

def getMenuDict(session):
    return MenuJson(session).getJson()

def getMenuHtmlString(session,metadataType):
    return MenuHtml(session,metadataType).getMenuHtml()

class MenuSerializer:
    def __init__(self,session):
        self.session =  session
        self.primaryRoleList = None
        self.secondaryRoleList = None
        self.applicationObj = self.session.getApplication()

    def validateUser(self, activity):
        if activity.getValue('AssignedTo'):
            assignedTo = activity.getValue('AssignedTo')
            if self.primaryRoleList is None:
                primaryUserRefcell = self.applicationObj.getSheetMetadata('RoleSubscription').getPublicCellMetadata("PrimaryUser")
                self.primaryRoleList = self.session.getList(self.session.getUser(), primaryUserRefcell)
            if validateGroup(assignedTo, self.primaryRoleList):
                return True
            else:
                if self.secondaryRoleList is None:
                    secondaryUserRefcell = self.applicationObj.getSheetMetadata('RoleSubscription').getPublicCellMetadata("SecondaryUser")
                    self.secondaryRoleList = self.session.getList(self.session.getUser(), secondaryUserRefcell)
                return validateGroup(assignedTo, self.secondaryRoleList)

        return True

class MenuJson(MenuSerializer):
    def __init__(self,session):
        MenuSerializer.__init__(self, session)
        self.menuDict=dict()

    def getJson(self):
        self.menuDict['root']=self.applicationObj.getSheetId()
        user = self.session.getUser()
        self.menuDict['current_user'] = {'SheetName': user.getSheetName(),'SheetId':user.getSheetId(),'Status':user.getValue('Status')}
        sheetMetadataList= self.applicationObj.getSheetMetadataList()
        folderList = self.applicationObj.getValue('Application.Folder')
        # Serializing Application Object
        self.menuDict[self.applicationObj.getSheetId()]={'SheetName':self.applicationObj.getSheetName(),
                                                         'SheetId':self.applicationObj.getSheetId(),
                                                         'Application.SheetMetadata':sheetMetadataList,
                                                         'AppRef.SheetMetadata':self.applicationObj.getValue('AppRef.SheetMetadata'),
                                                         'Application.Folder':folderList}

        # Serializing Public Sheet
        for sheetId in sheetMetadataList:
            sheetMetadata= self.applicationObj.getSheetMetadata(sheetMetadataList[sheetId])
            shortCutList = sheetMetadata.getShortCutList()
            if sheetMetadata.isPublic() and not sheetMetadata.isTrash():
                for shortCut in shortCutList:
                    self.serializeShortCut(shortCut)
                self.menuDict[sheetMetadata.getSheetId()]=self.serializeSheet(sheetMetadata)
        # Serializing folder
        for folderId in folderList:
            folderObj = self.applicationObj.getObject(folderId)
            self.serializeFolder(folderObj)
        return self.menuDict

    def serializeShortCut(self,shortCutMetadata):
        sheetMetadata=shortCutMetadata.getSheetMetadata()
        workflowBranch=sheetMetadata.getWorkFlowRoot()
        startActivity=workflowBranch.getActivityDefinitionList()[0]
        if (self.validateUser(startActivity)):
            shortCutDict=dict()
            shortCutDict['SheetId']=shortCutMetadata.getSheetId()
            shortCutDict['SheetName']=shortCutMetadata.getSheetName()
            shortCutDict['GridView']=shortCutMetadata.getValue('GridView')
            shortCutDict['SheetMetadata']=shortCutMetadata.getValue('SheetMetadata')
            self.menuDict[shortCutMetadata.getSheetId()] = shortCutDict

    def serializeFolder(self,folderMetadata):
        folderDict=dict()
        folderDict['SheetId']=folderMetadata.getSheetId()
        folderDict['SheetName']=folderMetadata.getSheetName()
        folderDict['Application']=folderMetadata.getValue('Application')
        folderDict['Folder.SheetMetadata']=folderMetadata.getValue('Folder.SheetMetadata')
        folderDict['Folder.ShortCut']=folderMetadata.getValue('Folder.ShortCut')
        folderList = folderMetadata.getValue('Folder.Folder')
        folderDict['Folder.Folder']=folderList
        for folderId in folderList:
            folderMetadataObj = self.applicationObj.getObject(folderId)
            self.serializeFolder(folderMetadataObj)
        self.menuDict[folderMetadata.getSheetId()]=folderDict

    def serializeSheet(self,sheetMetadata):
        sheetDict=dict()
        rootWFbranch = sheetMetadata.getWorkFlowRoot()
        startActivity=rootWFbranch.getActivityDefinitionList()[0]
        isSheetAccessable = self.validateUser(startActivity)
        sheetDict['SheetId']=sheetMetadata.getSheetId()
        sheetDict['SheetName']=sheetMetadata.getSheetName()
        sheetDict['PublicName']=sheetMetadata.getPublicName()
        oneToManyCellList= list()
        if isSheetAccessable:
            sheetDict['IsHidden']=sheetMetadata.getValue('IsHidden')
            oneToManyCellList=['SheetMetadata.ShortCut']
        else:
            sheetDict['IsHidden'] = 1.0
        manyToOneCellList=['Application','Folder']

#       oneToManyList
        for cellName in oneToManyCellList:
             sheetDict[cellName]=sheetMetadata.getValue(cellName)

#        Report
        searchDict = dict()
        for searchDef in  sheetMetadata.getSearchDefinitionList():
            if self.validateUser(searchDef):
                searchDict[searchDef.getSheetId()] =  searchDef.getSheetName()
        sheetDict['SheetMetadata.SearchDefinition'] = searchDict

        for cellName in manyToOneCellList:
            manytoOneValue=sheetMetadata.getValue(cellName)
            if manytoOneValue:
                sheetDict[cellName]=manytoOneValue

#       ActivityList
        sheetDict['StartActivityId'] = rootWFbranch.getActivityDefinitionList()[0].getSheetId()
        if rootWFbranch :
            activityDict=dict()
            for activity in rootWFbranch.getActivityDefinitionList():
                self.__getActivityList__(sheetMetadata, activity, activityDict)
            if len(activityDict) > 0:
                sheetDict["SheetMetadata.ActivityDefinition"]=activityDict
        return sheetDict

    def __getActivityList__(self, metadata, activity,activityDict):
            from orangescape.model.engine.engineconstants import OR_PROCESS, AND_PROCESS, REAL_OR_PROCESS
            if activity.getNodeType()==AND_PROCESS or activity.getNodeType()==OR_PROCESS or activity.getNodeType()==REAL_OR_PROCESS:
                for branch in activity.getBranchList():
                    for act in branch.getActivityDefinitionList():
                        self.__getActivityList__(metadata, act,activityDict)
            else:
                if activity.getNodeType() != 'GOTO' and self.validateUser(activity):
                    activityDict[activity.getSheetId()]=activity.getSheetName()

class MenuHtml(MenuSerializer):

    def __init__(self,session,metadataType):
        MenuSerializer.__init__(self, session)
        self.metadataType = metadataType

    def getMenuHtml(self):
        menuDict=dict()
        strBuffer = list()
        strBuffer.append("<ul>")

        strBuffer.append('<li><a href="/')
        strBuffer.append(self.applicationObj.getSheetId())
        strBuffer.append('/'+self.metadataType+'/home" style="padding-right:14px;padding-left:10px"><img src="/static/images/home.png"/></a></li>')

        for folder in self.applicationObj.getFolderList():
            folderStr = self.getFolderJson(folder)
            if len(folderStr)>9:
                strBuffer.append("<li><a href='#'>")
                strBuffer.append(folder.getSheetName())
                strBuffer.append("</a>")
                strBuffer.append(folderStr)
                strBuffer.append("</li>")

        for sheetMetadataId in self.applicationObj.getSheetMetadataList():
            sheetMetadata = self.applicationObj.getSheetMetadataById(sheetMetadataId)
            if sheetMetadata.getFolder() is None:
                self.constructSheetJson(sheetMetadata, strBuffer, menuDict)
            for shortcut in sheetMetadata.getShortCutList():
                if shortcut.getFolder() is None:
                    self.constructShortCutJson(shortcut, strBuffer, menuDict)

        strBuffer.append("</ul>")
        return "".join(strBuffer)


    def getFolderJson(self, subFolder):
        folderDict=dict()
        strBuffer = list()
        strBuffer.append("<ul>")

        for folder in subFolder.getFolderList():
            folderStr = self.getFolderJson(folder)
            if len(folderStr)>9:
                strBuffer.append("<li><a href='#'>")
                strBuffer.append(folder.getSheetName())
                strBuffer.append("</a>")
                strBuffer.append(folderStr)
                strBuffer.append("</li>")

        for sheetMetadataId in subFolder.getSheetMetadataList():
            sheetMetadata = self.applicationObj.getSheetMetadataById(sheetMetadataId)
            self.constructSheetJson(sheetMetadata, strBuffer, folderDict)
        for shortcut in subFolder.getShortCutList():
            self.constructShortCutJson(shortcut, strBuffer, folderDict)

        strBuffer.append("</ul>")
        return "".join(strBuffer)


    def constructSheetJson(self, sheetMetadata, strBuffer=None, menuDict=None):
        if sheetMetadata.isPublic() and not sheetMetadata.isTrash():
            if not sheetMetadata.getValue('IsHidden'):
                workflowBranch=sheetMetadata.getWorkFlowRoot()
                startActivity=workflowBranch.getActivityDefinitionList()[0]
                if (self.validateUser(startActivity)):
                    strBuffer.append("<li><a href='")
                    strBuffer.append("/"+self.applicationObj.getSheetId()+"/"+self.metadataType+"/"+sheetMetadata.getSheetId()+"/"+startActivity.getSheetId()+"/"+sheetMetadata.getSheetId()+"?mimetype=text/html&__method=POST")
                    strBuffer.append("'>")
                    strBuffer.append(sheetMetadata.getPublicName())
                    strBuffer.append("</a></li>")

            # to show reports in menu
            reportList = sheetMetadata.getSearchDefinitionList()
            for report in reportList:
                if (self.validateUser(report)):
                    strBuffer.append("<li><a href='")
                    strBuffer.append("/"+self.applicationObj.getSheetId()+"/"+self.metadataType+"/"+sheetMetadata.getSheetId()+"/report/"+report.getSheetId()+"?mimetype=text/html")
                    strBuffer.append("'>")
                    strBuffer.append(report.getSheetName())
                    strBuffer.append("</a></li>")

    def constructShortCutJson(self, shortCut, strBuffer=None, menuDict=None):
        sheetMetadata=shortCut.getSheetMetadata()
        formName = ""
        if sheetMetadata.isPublic() and not sheetMetadata.isTrash():
            if shortCut.getGridView():
                gridViewName = shortCut.getGridView()
                if gridViewName:
                    formName = "&form="+gridViewName
            workflowBranch=sheetMetadata.getWorkFlowRoot()
            startActivity=workflowBranch.getActivityDefinitionList()[0]
            if (self.validateUser(startActivity)):
                strBuffer.append("<li><a href='")
                strBuffer.append("/"+self.applicationObj.getSheetId()+"/"+self.metadataType+"/"+sheetMetadata.getSheetId()+"/"+startActivity.getSheetId()+"/"+sheetMetadata.getSheetId()+"?mimetype=text/html&__method=POST&ShortCut="+shortCut.getSheetName()+formName)
                strBuffer.append("'>")
                strBuffer.append(shortCut.getSheetName())
                strBuffer.append("</a></li>")
