from orangescape.model.server.Context import getApplication
import appconfig as config
from orangescape.model.server.Constants import EDITOR,INBOX,REPORT,WORKTOP,SEARCH
from orangescape.model.server.commands.CommandUtil import getUrlParams
import os
import logging

class Page:
    def getPortlets(self):
        pass

    def getPortlet(self, portletId):
        pass

class Portlet:
    def __init__(self, controller, portletId, jsonUrl, jstlFile, form, filter = "{}"):
        self.controller = controller
        self.portletId = portletId
        self.url = jsonUrl
        self.jstlFile = jstlFile
        self.form = form
        self.filter = filter
        self.request = self.controller.request
        self.urlList = getUrlParams(self.request.path)

    def getPortletId(self):
        return self.portletId

    def getControllerType(self):
        if self.jstlFile:
            return "runtime_controller"
        return "preview_controller"

    def getTypeName(self):
        raise NotImplementedError

    def getUrl(self):
        return self.url

    def getForm(self):
        return self.form

    def getJstlFile(self):
        return self.jstlFile

    def getFilter(self):
        return self.filter

    def getConfig(self):
        return None

class EditorPortlet(Portlet):
    def getTypeName(self):
        return EDITOR

class InboxPortlet(Portlet):
    def getTypeName(self):
        return INBOX

class SearchPortlet(Portlet):
    def getTypeName(self):
        return SEARCH

class ReportPortlet(Portlet):
    reportPref = None
    def getControllerType(self):
        if self.reportPref:
            return "aggregatereport_controller"
        return "report_controller"

    def getTypeName(self):
        if self.reportPref:
            return REPORT
        return INBOX

    def getConfig(self):
        if self.reportPref:
            return self.reportPref
        session = self.controller.getSession()
        searchDefId = self.urlList.pop()
        if session.getApplication().getSheetMetadataDict().__contains__('ReportPreference'):
            reportPrefMetadata = session.getApplication().getSheetMetadata('ReportPreference')
            self.reportPref = session.getIfExists(searchDefId, reportPrefMetadata)
        return self.reportPref

    def getDefaultFilter(self):
        from orangescape.model.server.util.ReportSerializer import serializeFilterInfo
        urlList = getUrlParams(self.request.path)
        searchDefId = urlList[4]
        #urlList.pop()
        sheetmetadata = self.controller.getSession().getApplication().getSheetMetadataById(urlList[2])
        searchDef = sheetmetadata.getSearchDefinitionById(searchDefId)
        filter=None
        if self.getConfig() and self.getConfig().getValue('Filter'):
            configfilter = self.getConfig().getValue('Filter')
            from json import read
            filter = read(configfilter)
        jsonStr = '{'+serializeFilterInfo(searchDef, self.request.path, filter)+'}'
        return jsonStr

class WorktopPortlet(ReportPortlet):
    def getControllerType(self):
        return "aggregatereport_controller"

    def getTypeName(self):
        return WORKTOP

class Context:
    def __init__(self, session=None):
        self.session = session
        self.globalIns = None
        self.companyIns = None
        self.userLoginIns = None
        self.userChangeIns = None

    def getSession(self):
        return self.session

    def getInstance(self, modelName, instanceId):
        modelMetadata = self.getSession().getApplication().getSheetMetadata(modelName)
        return self.getSession().get(instanceId, modelMetadata)

    def getGlobal(self):
        if self.globalIns:
            return self.globalIns
        if self.getSession() and self.getSession().getApplication().getSheetMetadataDict().__contains__('Global'):
            globalSheetMetadata=self.getSession().getApplication().getSheetMetadata('Global')
            companySheetMetadata = self.getSession().getApplication().getSheetMetadata('Company')
            if companySheetMetadata.getPublicCellMetadataDict().__contains__('Global') and self.getCompany():
                globalId = self.getCompany().getValue('Global')
                if globalId:
                    self.globalIns = self.getSession().get(globalId, globalSheetMetadata)
                    return self.globalIns

    def getCompany(self):
        if self.companyIns:
            return self.companyIns
        companySheetMetadata = self.getSession().getApplication().getSheetMetadata('Company')
        companyId = self.getUser().getValue('Company')
        if companyId:
            self.companyIns = self.getSession().get(companyId, companySheetMetadata)
            return self.companyIns

    def getUser(self):
        return self.getSession().getUser()

    def getFirstTimeLogin(self):
        if self.userChangeIns:
            return self.userChangeIns.getValue('FirstTimeLogin')
        if self.getSession() and self.getSession().getApplication().getSheetMetadataDict().__contains__('UserChanges'):
            userChangesSheetMetadata = self.getSession().getApplication().getSheetMetadata('UserChanges')
            userChangeId = self.getUser().getValue('Current')

            if userChangeId:
                self.userChangeIns = self.getSession().get(userChangeId, userChangesSheetMetadata)
                return self.userChangeIns.getValue('FirstTimeLogin')
        else:
            return True

    def getUserLogin(self):
        if self.userLoginIns:
            return self.userLoginIns
        userLoginSheetMetadata = self.getSession().getApplication().getSheetMetadata('UserLoginModel')
        userLoginId = self.getUser().getValue('UserLoginModel')
        if userLoginId:
            self.userLoginIns = self.getSession().get(userLoginId, userLoginSheetMetadata)
            return self.userLoginIns

    def getNative(self):
        return self.session

class Metadata:
    def __init__(self,session = None):
        self.session = session
        self.application = getApplication()

    def getSession(self):
        return self.session

    def getApplication(self):
        if self.getSession():
            return self.getSession().getApplication()
        return self.application

    def getModel(self, modelName):
        return self.getApplication().getSheetMetadata(modelName)

    def getMetadataId(self, modelNamelist):
        from json import write
        from orangescape.model.engine.engineconstants import OR_PROCESS, AND_PROCESS, REAL_OR_PROCESS
        strBuffer = list()
        userCellMetadataDict = self.getSession().getUser().getSheetMetadata().getPublicCellMetadataDict()
        strBuffer.append("{")
        strBuffer.append(write("CurrentUserId"))
        strBuffer.append(":")
        strBuffer.append(write(self.getSession().getUser().getSheetId()))
        strBuffer.append(",")
        strBuffer.append(write("ApplicationId"))
        strBuffer.append(":")
        strBuffer.append(write(self.application.getSheetId()))
        strBuffer.append(",")
        strBuffer.append(write("ApplicationName"))
        strBuffer.append(":")
        strBuffer.append(write(self.application.getSheetName()))
        if userCellMetadataDict.get("UserProfile") and self.getSession().getUser().getValue('UserProfile')=='Administration':
            for modelName in modelNamelist:
                sheetMetadata = self.getModel(modelName)
                strBuffer.append(",")
                strBuffer.append(write(sheetMetadata.getValue('SheetName') ))
                strBuffer.append(":{")
                strBuffer.append(write("SheetId"))
                strBuffer.append(":")
                strBuffer.append(write(sheetMetadata.getSheetId()))
                strBuffer.append(",")
                rootWFbranch = sheetMetadata.getWorkFlowRoot()
                if rootWFbranch:
                    strBuffer.append(write("Activity"))
                    strBuffer.append(":{")
                    flag =0
                    for activity in rootWFbranch.getActivityDefinitionList():
                        if activity.getNodeType()!=AND_PROCESS and activity.getNodeType()!=OR_PROCESS and activity.getNodeType()!=REAL_OR_PROCESS and activity.getNodeType() != 'GOTO':
                            if flag != 0:
                                strBuffer.append(",")
                            else:
                                flag = 1
                            strBuffer.append(write(activity.getSheetName()))
                            strBuffer.append(":")
                            strBuffer.append(write(activity.getSheetId()))

                    strBuffer.append("}")
                    strBuffer.append("}")
        strBuffer.append("}")
        return ''.join(strBuffer)

    def getMenu(self):
        if self.getSession():
            from menuserialization import getMenuDict
            return getMenuDict(self.getSession())
        return dict()

class HttpRequest:
    def __init__(self, request):
        self.request = request

    def getParameters(self):
        paramsDict = dict()
        if self.request:
            paramsDict.update(self.request.params)
        return paramsDict

    def getSessionId(self):
        return ''

    def getCurrentUrl(self):
        return self.request.path

    def getNative(self):
        return self.request

class Helper:
    homeUrl = None
    logoutUrl = None
    metadataType = "1"

    def setHomeUrl(self, homeUrl):
        self.homeUrl = homeUrl

    def getHomeUrl(self):
        if self.homeUrl:
            return self.homeUrl
        return "/"+getApplication().getSheetId()+"/1/home"

    def setLogoutUrl(self, logoutUrl):
        self.logoutUrl = logoutUrl

    def getLogoutUrl(self):
        if self.logoutUrl:
            return self.logoutUrl
        else:
            if config.env==config.ENTERPRISE:
                from orangescape.model.server.util.ServerUtil import _get_class
                return _get_class(config.AUTHENTICATION)().getLogoutUrl()
            return "/"+getApplication().getSheetId()+"/1/logout"

    def setMetadataType(self, metadataType):
        self.metadataType = metadataType

    def getMetadataType(self):
        return self.metadataType

    def getToday(self, format = "%d-%b-%Y"):
        from time import strftime
        return strftime(format)

    def getMetadataVersion(self):
        return config.metadataVersion
