import appconfig as config
from routes.mapper import Mapper
from webob import Request
import logging

def isWebService(environ, result):
        req = Request(environ)
        if(req.params.getall("wsdl")):
            return True
        else:
            return False

def referals(environ, result):
        req = Request(environ)
        if(req.params.get('action', False)):
            if(req.method=='PUT' and req.params['action']=='submit'):
                return True
        else:
            return False

def isAttachment(environ, result):
        req = Request(environ)
        url=req.path_info
        path=url[1:len(url)].split('/')
        if(path[len(path)-1]=='attachment'):
            return True
        else:
            return False

def isCheckout(environ, result):
        req = Request(environ)
        url=req.path_info
        path=url[1:len(url)].split('/')
        return (path[len(path)-1]=='checkout') or (path[len(path)-1]=='commit')

def isCsvimport(environ, result):
        req = Request(environ)
        url=req.path_info
        path=url[1:len(url)].split('/')
        return path[len(path)-1]=='csvimport'

def isSerializeApplication(environ, result):
    req = Request(environ)
    url=req.path_info
    path=url[1:len(url)].split('/')
    return (path[len(path)-1]=='application')

def isInstance(environ, result):
        req = Request(environ)
        url=req.path_info
        path=url[1:len(url)].split('/')

        if(path[len(path)-1]=='list'):
            return False
        else:
            return True

def iscustomfunction(environ, result):
        req = Request(environ)
        if(req.params.get('action', False)):
            if(req.params['action']=='invoke'):
                return True
            else:
                return False
        else:
            return False

def getInstanceController():

    if config.env==config.ENTERPRISE:
        return 'orangescape.model.server.commands.ECommandFactory:ECommandFactory'
    elif config.env in (config.TEST, config.GAE, config.GAESQL):
        return 'orangescape.model.server.commands.GAECommandFactory:GAECommandFactory'
    elif config.env== config.AZURE:
        return 'orangescape.model.server.commands.AzureCommandFactory:AzureCommandFactory'
    elif config.env== config.SL:
        return 'SLCommandFactory:SLCommandFactory'

def getMigrationController():

    if config.env in (config.ENTERPRISE, config.GAESQL):
        return 'orangescape.model.server.commands.SQLMigration:SQLMigration'
    elif config.env in (config.TEST, config.GAE, config.GAESQL):
        return 'orangescape.model.server.migration.GAESQLMigrationFactory:GAESQLMigrationFactory'
    elif config.env== config.AZURE:
        return 'orangescape.model.server.migration.AzureSQLMigrationFactory:AzureSQLMigrationFactory'
    elif config.env== config.SL:
        return 'SLCommandFactory:SLCommandFactory'

def getActivityController():
    if config.env==config.ENTERPRISE:
        return 'orangescape.model.server.commands.ECommandFactory:ECommandFactory'
    elif config.env in (config.TEST, config.GAE, config.GAESQL):
        return 'orangescape.model.server.commands.GAECommandFactory:GAECommandFactory'
    elif config.env== config.AZURE:
        return 'orangescape.model.server.commands.AzureCommandFactory:AzureCommandFactory'
    elif config.env== config.SL:
        return 'SLCommandFactory:SLCommandFactory'

def getDataViewer():
    if config.env==config.ENTERPRISE:
        return 'orangescape.model.server.db.EDataViewer:EDataViewer'
    elif config.env in (config.TEST, config.GAE, config.GAESQL):
        return 'orangescape.model.server.DataViewer:DataViewer'

def make_map():

        map = Mapper(explicit = True, register = False)
        map.connect('/{applicationid}/{metadatatype}/administrator', controller=getDataViewer(), action='getDetails')
        map.connect('/{applicationid}/{metadatatype}/administrator/*url', controller=getDataViewer() , action='getData')

        map.connect('/{applicationid}/{metadatatype}/migrate/application', controller=getMigrationController(), action='application',section='open')
        map.connect('/{applicationid}/{metadatatype}/migrate/setattachments', controller=getMigrationController(), action='setattachments',section='open')
#        map.connect('/{applicationid}/{metadatatype}/migrate/generatescripts', controller=getMigrationController(), action='generatescripts')
        map.connect('/{applicationid}/{metadatatype}/migrate/sheetmetadata/*url', controller=getMigrationController(), action='sheetmetadata',section='open')
        map.connect('/{applicationid}/{metadatatype}/migrate/executescripts', controller=getMigrationController(), action='executescripts',section='open')

#        map.connect('/{applicationid}/{metadatatype}/migrate/*url', controller=getMigrationController(), action='getDiff')

        """studio based mapping"""
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/*url/viewversions', controller=getInstanceController(), action='modelversions')
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/*url/downloadversion', controller=getInstanceController(), action='downloadversion')
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/*url/application', controller=getInstanceController(), action='serializeApplication', conditions=dict(method=['GET'],function=isSerializeApplication))
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/*url/replaceattachment', controller=getInstanceController(), action='replaceAttachment', conditions=dict(method=['PUT']))
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/*url/formdata', controller=getInstanceController(), action='serializeFormData')

        map.connect('/migrate/clearCache', controller='orangescape.model.server.Repair:Migrate', action='clearCache',section='open')
        map.connect('/migrate/updateAppRef', controller='orangescape.model.server.Repair:Migrate', action='updateAppRef')
        map.connect('/migrate/updateAppSubscription', controller='orangescape.model.server.Repair:Migrate', action='updateAppSubscription')
        map.connect('/migrate/unlockModel', controller='orangescape.model.server.Repair:Migrate', action='unlockModel')


        """runtime flatimport,sla,cache clearing mapping"""
        map.connect('/{applicationid}/{metadatatype}/flatcsvimport', controller='orangescape.model.server.integration.FlatCsvImporter:FlatCsvImport', action='post')
        map.connect('/{applicationid}/{metadatatype}/triggersla', controller=getInstanceController(), action='triggersla', section='open')
        map.connect('/clearcache', controller=getInstanceController(), action='clearCache',section='open')

        """webserice based mapping"""
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/*url', controller=getInstanceController(), action='wsdl', section='open', conditions=dict(function=isWebService))
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/ws', controller=getInstanceController(), action='invokeWS', section='open', conditions=dict(method=['POST']))

        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/query', controller=getActivityController(), action='queryByTable', section='admin', conditions=dict(method=['GET']))

        """Mapping for report sync api"""
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/keys', controller=getActivityController(), action='keysByActivity', section='admin', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/query', controller=getActivityController(), action='queryByActivity', section='admin', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/query', controller=getActivityController(), action='getbykeysByActivity', section='admin', conditions=dict(method=['POST']))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/aggregate', controller=getActivityController(), action='aggregateEntitiesByActivity', conditions=dict(method=['GET']))

        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/keys/:secondaryuser', controller=getActivityController(), action='keysByActivity', section='admin', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/query/:secondaryuser', controller=getActivityController(), action='queryByActivity', section='admin', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/query/:secondaryuser', controller=getActivityController(), action='getbykeysByActivity', section='admin', conditions=dict(method=['POST']))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/aggregate/:secondaryuser', controller=getActivityController(), action='aggregateEntitiesByActivity', section='admin', conditions=dict(method=['GET']))

        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/{instanceId}/{cellName}/keys', controller=getActivityController(), action='keys', section='admin', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/{instanceId}/{cellName}/query', controller=getActivityController(), action='query', section='admin', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/{instanceId}/{cellName}/query', controller=getActivityController(), action='getbykeys', section='admin', conditions=dict(method=['POST']))
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/{instanceId}/{cellName}/aggregate', controller=getActivityController(), action='aggregate', conditions=dict(method=['GET']))

        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/report/{searchdefinitionid}/keys', controller=getActivityController(), action='keysBySearch', section='admin', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/report/{searchdefinitionid}/query', controller=getActivityController(), action='queryBySearch', section='admin', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/report/{searchdefinitionid}/query', controller=getActivityController(), action='getbykeysBySearch', section='admin', conditions=dict(method=['POST']))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/report/{searchdefinitionid}/meta', controller=getActivityController(), action='getMetaInfo', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/report/{searchdefinitionid}/aggregate', controller=getActivityController(), action='aggregateEntitiesBySearch', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/report/{searchdefinitionid}/{mastersearchid}',controller=getActivityController(), action='readforMasterReport', conditions=dict(method=['GET']))

        """Mapping for normal Report"""
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/report/{searchdefinitionid}', controller=getActivityController(), action='readforReport', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/report/{searchdefinitionid}/p{pageNumber}/{pageCount}', controller=getActivityController(), action='readforReport', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/report/{searchdefinitionid}/{sheetmetadataid}/{sheetid}', controller=getActivityController(), action='readforInstanceReport', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/report/{searchdefinitionid}/{sheetmetadataid}/{sheetid}', controller=getActivityController(), action='invokeforReport',conditions=dict(function=iscustomfunction))

        """Mapping for Inbox """
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}', controller=getActivityController(), action='readforInbox', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/p{pageNumber}', controller=getActivityController(), action='readforInbox', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/p{pageNumber}/{pageCount}', controller=getActivityController(), action='readforInbox', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/p{pageNumber}/{pageCount}', controller=getActivityController(), action='updateUser', conditions=dict(method=['PUT']))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/p{pageNumber}/{pageCount}/*url', controller=getInstanceController(), action='deleteforInbox', conditions=dict(method=['DELETE'],function=isInstance))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/p{pageNumber}/{pageCount}', controller=getActivityController(), action='invokeforInbox', conditions=dict(function=iscustomfunction))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/p{pageNumber}/{pageCount}/*url', controller=getActivityController(), action='invokeforInbox', conditions=dict(function=iscustomfunction))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/p{pageNumber}/{pageCount}/{cellName}/search', controller=getActivityController(), action='searchUser', conditions=dict(method=['GET']))

        #for secondary user
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/:SecondaryUser', controller=getActivityController(), action='readforInbox', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/:SecondaryUser/p{pageNumber}/{pageCount}', controller=getActivityController(), action='readforInbox', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/:SecondaryUser/p{pageNumber}/{pageCount}', controller=getActivityController(), action='updateUser', conditions=dict(method=['PUT']))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/:SecondaryUser/p{pageNumber}/{pageCount}/*url', controller=getInstanceController(), action='deleteforInbox', conditions=dict(method=['DELETE'],function=isInstance))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/:SecondaryUser/p{pageNumber}/{pageCount}', controller=getActivityController(), action='invokeforInbox', conditions=dict(function=iscustomfunction))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/:SecondaryUser/p{pageNumber}/{pageCount}/*url', controller=getActivityController(), action='invokeforInbox', conditions=dict(function=iscustomfunction))
        map.connect('/{applicationid}/{metadatatype}/{sheetmetadataid}/{activitydefinitionid}/:SecondaryUser/p{pageNumber}/{pageCount}/{cellName}/search', controller=getActivityController(), action='searchUser', conditions=dict(method=['GET']))

        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/{instanceId}/{cellName}/search', controller=getActivityController(), action='readforSearch', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/{instanceId}/{cellName}/search/p{pageNumber}/{pageCount}', controller=getActivityController(), action='readforSearch', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/{instanceId}/*url/{cellName}/search', controller=getActivityController(), action='readforSearch', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/{instanceId}/*url/{cellName}/search/p{pageNumber}/{pageCount}', controller=getActivityController(), action='readforSearch', conditions=dict(method=['GET']))

        """attachment based mapping"""
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/*url/attachment', controller=getInstanceController(), action='getAttachmentWithId', conditions=dict(method=['GET'],function=isAttachment))
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/*url/attachment', controller=getInstanceController(), action='updateAttachmentWithId', conditions=dict(method=['POST'],function=isAttachment))
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/*url/attachment', controller=getInstanceController(), action='deleteAttachmentWithId', conditions=dict(method=['DELETE'],function=isAttachment))
        """attachment for bulk mapping"""
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/*url/bulkattach', controller=getInstanceController(), action='attach', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/*url/attachment', controller=getInstanceController(), action='updateAttachment', conditions=dict(method=['PUT'],function=isAttachment))
        """attachment unused mapping"""
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/*url/attach', controller=getInstanceController(), action='attachWithId', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/*url/getattachment', controller=getInstanceController(), action='getAttachment', conditions=dict(method=['GET']))

        """editor based mapping"""
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}', controller=getInstanceController(), action='new',conditions=dict(method=['POST']))
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/*url', controller=getInstanceController(), action='invoke',conditions=dict(function=iscustomfunction))

        """studio based mapping"""
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/*url/commit', controller=getInstanceController(), action='commit', conditions=dict(method=['POST'],function=isCheckout))

        """editor based mapping"""
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/*url/csvimport', controller=getInstanceController(), action='csvimport', conditions=dict(method=['POST'],function=isCsvimport))
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/*url', controller=getInstanceController(), action='create', conditions=dict(method=['POST']))

        """studio based mappig"""
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/*url/checkout', controller=getInstanceController(), action='checkout', conditions=dict(method=['GET'],function=isCheckout))

        """for deleting attachment """
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/*url/attachment', controller=getInstanceController(), action='deleteAttachment', conditions=dict(method=['DELETE'],function=isAttachment))

        """editor based mapping"""
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/*url', controller=getInstanceController(), action='read', conditions=dict(method=['GET'],function=isInstance))
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/*url', controller=getInstanceController(), action='update', conditions=dict(method=['PUT'],function=isInstance))
        map.connect('/{applicationid}/{metadatatype}/{parentsheetmetadataid}/{taskid}/{sheetmetadataid}/*url', controller=getInstanceController(), action='deleteAction', conditions=dict(method=['DELETE'],function=isInstance))

        """studio loading and creating models"""
        map.connect('/studio', controller=getInstanceController(), action='openModel', conditions=dict(method=['PUT']))
        map.connect('/studio', controller=getInstanceController(), action='createModel', conditions=dict(method=['POST']))
        map.connect('/reload', controller=getInstanceController(), action='reloadModel', conditions=dict(method=['PUT']))

        """login,home page mapping"""
        map.connect('/{applicationid}/{metadatatype}/signin', controller=getInstanceController(), action='processLogin',section='open', conditions=dict(method=['POST']))
        map.connect('/{applicationid}/{metadatatype}/signin', controller=getInstanceController(), action='renderLogin', section='open', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/schemasync', controller=getInstanceController(), action='schemaSync', section='open', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/metadatasync', controller=getInstanceController(), action='metadataSync', section='open', conditions=dict(method=['GET']))
        map.connect('/{applicationid}/{metadatatype}/authenticate', controller=getInstanceController(), action='authenticate', section='open')
        map.connect('/{applicationid}/{metadatatype}/menu', controller=getInstanceController(), action='menu')
        map.connect('/{applicationid}/{metadatatype}/worktop', controller=getInstanceController(), action='renderWorktop')
        map.connect('/{applicationid}/{metadatatype}/teamworktop', controller=getInstanceController(), action='renderWorktop')
        map.connect('/{applicationid}/{metadatatype}/home', controller=getInstanceController(), action='renderHome')
        map.connect('/', controller=getInstanceController(), action='renderHome')
        map.connect('/_ah/login_required', controller=getInstanceController(), action='renderLogin',section='open', conditions=dict(method=['GET']))
        map.connect('{applicationid}/{metadatatype}/logout', controller=getInstanceController(), action='logout')

        """incoming email mapping"""
        map.connect('/_ah/mail/*url', controller=getInstanceController(), action='receiveMail',section='open', conditions=dict(method=['POST']))

        """For backend Start"""
        map.connect('/_ah/start', controller=getInstanceController(), action='backendStart',section='open', conditions=dict(method=['GET']))

        """testcases based mapping"""
        map.connect('/test', controller=getInstanceController(), action='renderTest')
        map.connect('/testdata',controller='orangescape.tests.functional.server.app_setup:TestData', action='get')
        map.connect('/model/gae', controller='orangescape.tests.functional.server.dev.TestModelDesign:TestModelOnGae', action='get')

        return map