#!/usr/bin/env python

import copy
import types
import re

from dm.common.exceptions.dmException import DmException
from dm.common.mongodb.api.dmMongoDbApi import DmMongoDbApi
from dm.common.mongodb.impl.workflowCollection import WorkflowCollection
from dm.common.mongodb.api.dmMongoDbApi import DmMongoDbApi
from dm.common.objects.workflow import Workflow
from dm.common.exceptions.invalidRequest import InvalidRequest

class WorkflowMongoDbApi(DmMongoDbApi):

    SYSTEM_KEY_LIST = ['_id', 'name', 'owner']

    def __init__(self):
        DmMongoDbApi.__init__(self)
        self.workflowCollectionDict = {}

    def getWorkflowCollection(self, owner):
        workflowCollection = self.workflowCollectionDict.get(owner)
        if not workflowCollection:
            workflowCollection = WorkflowCollection(self.dbClient, owner)
            self.workflowCollectionDict[owner] = workflowCollection
        return workflowCollection

    @classmethod
    def getAndCheckOwner(cls, dictObject):
        owner = dictObject.get('owner')
        cls.checkOwner(owner)
        return owner

    @classmethod
    def checkOwner(cls, owner):
        if not owner:
            raise InvalidRequest('Owner name has not been provided.')

    @DmMongoDbApi.executeDbCall
    def addWorkflow(self, workflow, **kwargs):
        owner = self.getAndCheckOwner(owner)
        workflow2 = self.getMongoDict(workflow)
        dbWorkflow = self.getWorkflowCollection(owner).addByUniqueKeys(workflow2)
        return self.toDmObject(dbWorkflow, Workflow)

    @DmMongoDbApi.executeDbCall
    def getWorkflows(self, owner, queryDict={}, returnFieldDict=WorkflowCollection.ALL_FIELDS_DICT, **kwargs):
        self.checkOwner(owner)
        queryDict2 = self.getMongoDict(queryDict)
        ignoreCase = kwargs.get(self.REGEX_IGNORE_CASE_KEY, True)
        queryDict2 = self.convertStringsToRegex(queryDict2, ignoreCase)
        return self.listToDmObjects(self.getWorkflowCollection(owner).findByQueryDict(queryDict2, returnFieldDict), Workflow)

    @DmMongoDbApi.executeDbCall
    def getWorkflowById(self, owner, id, **kwargs):
        self.checkOwner(owner)
        dbWorkflow = self.getWorkflowCollection(owner).findById(id)
        return self.toDmObject(dbWorkflow, Workflow)

    @DmMongoDbApi.executeDbCall
    def getWorkflowByName(self, owner, name, **kwargs):
        self.checkOwner(owner)
        queryDict = { 'name' : name, 'owner' : owner }
        dbWorkflow = self.getWorkflowCollection(owner).findByUniqueKeys(queryDict)
        return self.toDmObject(dbWorkflow, Workflow)

    @DmMongoDbApi.executeDbCall
    def updateWorkflowById(self, workflow, **kwargs):
        owner = self.getAndCheckOwner(workflow)
        workflow2 = self.getMongoDict(workflow)
        dbWorkflow = self.getWorkflowCollection(owner).updateById(workflow2)
        return self.toDmObject(dbWorkflow, Workflow)

    @DmMongoDbApi.executeDbCall
    def updateWorkflow(self, workflow, **kwargs):
        owner = self.getAndCheckOwner(workflow)
        workflow2 = self.getMongoDict(workflow)
        dbWorkflow = self.getWorkflowCollection(owner).updateByUniqueKeys(workflow2)
        return self.toDmObject(dbWorkflow, Workflow)

    @DmMongoDbApi.executeDbCall
    def updateOrAddWorkflow(self, workflow, **kwargs):
        owner = self.getAndCheckOwner(workflow)
        workflow2 = self.getMongoDict(workflow)
        dbWorkflow = self.getWorkflowCollection(owner).updateOrAddByUniqueKeys(workflow2)
        return self.toDmObject(dbWorkflow, Workflow)

#######################################################################
# Testing.
if __name__ == '__main__':
    from dm.common.mongodb.impl.mongoDbManager import MongoDbManager
    mgr = MongoDbManager.getInstance()
    mgr.dbName = 'dm'
    api = WorkflowMongoDbApi()

    workflows = api.getWorkflows('sveseli')
    for workflow in workflows:
        print 'WORKFLOW: %s\n' % workflow.getDictRep()

    workflow = api.getWorkflowByName('sveseli', 'workflow-01')
    print 'WORKFLOW: %s\n' % workflow.getDictRep()