#! /usr/bin/env python
#############################################################
#                                                           #
#   Author: Herve Menager                                   #
#   Organization:'Biological Software and Databases' Group, #
#                Institut Pasteur, Paris.                   #
#   Distributed under GPLv2 Licence. Please refer to the    #
#   COPYING.LIB document.                                   #
#                                                           #
#############################################################
import mb_cgi
from Mobyle.Workflow import Workflow, Task, Parameter, Link, Type, Datatype, Biotype, InputValue,\
    Parser

def process( self ):
    object = self.request.getfirst("object")
    action = self.request.getfirst("action")
    if object=='workflow':
        if action in ["create","update"]:
            if action=="create":
                workflow = Workflow()
                self.session.addWorkflow(workflow)
            elif action=="update":
                workflow_id = int(self.request.getfirst('workflow_id'))
                workflow = self.session.readWorkflow(workflow_id)
            if self.request.has_key('name'):
                name = self.request.getfirst('name')
                workflow.name = name
            if self.request.has_key('version'):
                version = self.request.getfirst('version')
                workflow.version = version
            if self.request.has_key('title'):
                title = self.request.getfirst('title')
                workflow.title = title
            if self.request.has_key('authors'):
                authors = self.request.getfirst('authors')
                workflow.authors = authors
            if self.request.has_key('description'):
                description = self.request.getfirst('description')
                workflow.description = description
            self.session.saveWorkflow(workflow)
            self.xmltext = render_model(workflow)
        elif action=="get":
            workflow_id = int(self.request.getfirst('workflow_id'))
            workflow = self.session.readWorkflow(workflow_id)
            self.xmltext = render_model(workflow)
        elif action=="list":
            ids = self.session.getWorkflows()
            self.xmltext = ids
        elif action=="get_url":
            workflow_id = int(self.request.getfirst('workflow_id'))
            url = self.session.getWorkflowUrl(workflow_id)
            self.xmltext = url
    elif object=='task':
        if action in ["create","update"]:
            if action=="create":
                workflow_id = int(self.request.getfirst('workflow_id'))
                workflow = self.session.readWorkflow(workflow_id)
                ids = [int(task.id) for task in workflow.tasks]
                if ids:
                    id = max(ids)+1
                else:
                    id = 1
                task = Task()
                task.id = id
                workflow.tasks = workflow.tasks + [task]
            elif action=="update":
                workflow_id = int(self.request.getfirst('workflow_id'))
                task_id = int(self.request.getfirst('task_id'))
                workflow = self.session.readWorkflow(workflow_id)
                task = [t for t in workflow.tasks if int(t.id)==task_id][0]
            if self.request.has_key('service_pid'):
                service_pid = self.request.getfirst('service_pid')
                task.service = service_pid
            if self.request.has_key('suspend'):
                suspend = bool(self.request.getfirst('suspend')=='true')            
                task.suspend = ("false","true")[suspend]
            if self.request.has_key('description'):
                description = self.request.getfirst('description')
                task.description = description
            # setting task parameter default values
            for key in self.request.keys():
                if key.startswith('parameter::'):
                    name = key.split('::')[1]
                    value = self.request.getfirst('parameter::%s' % name,'')
                    if value!='':
                        # set a value for a parameter
                        input_values = [iv for iv in task.input_values if iv.name==name]
                        if len(input_values)>0:
                            input_value=input_values[0]
                        else:
                            input_value=InputValue()
                            input_value.name=name
                            task.input_values = task.input_values + [input_value]
                        input_value.value=value
                    else:
                        # unset a value for a parameter
                        input_values = [iv for iv in task.input_values if iv.name!=name]
                        task.input_values = input_values
            # creating a link from or to the task along the way
            if self.request.has_key('from_parameter') or self.request.has_key('from_parameter'):
                ids = [int(link.id) for link in workflow.links]
                if ids:
                    id = max(ids)+1
                else:
                    id = 1
                link = Link()
                link.id = id
                workflow.links = workflow.links + [link]
                if self.request.has_key('from_parameter'):
                    from_parameter = self.request.getfirst('from_parameter')
                    link.from_parameter = from_parameter
                if self.request.has_key('from_task'):
                    from_task = self.request.getfirst('from_task')
                    if from_task=='self':
                        from_task = task.id
                    link.from_task = from_task
                if self.request.has_key('to_parameter'):
                    to_parameter = self.request.getfirst('to_parameter')
                    link.to_parameter = to_parameter
                if self.request.has_key('to_task'):
                    to_task = self.request.getfirst('to_task')
                    if to_task=='self':
                        to_task = task.id
                    link.to_task = to_task
            self.session.saveWorkflow(workflow) 
            self.xmltext = render_model(task)
        elif action=="get":
            workflow_id = int(self.request.getfirst('workflow_id'))
            task_id = int(self.request.getfirst('task_id'))
            workflow = self.session.readWorkflow(workflow_id)
            task = [t for t in workflow.tasks if int(t.id)==task_id][0]
            self.xmltext = render_model(task)
        elif action=="delete":
            workflow_id = int(self.request.getfirst('workflow_id'))
            task_id = int(self.request.getfirst('task_id'))
            workflow = self.session.readWorkflow(workflow_id)
            tasks = [t for t in workflow.tasks if int(t.id)!=task_id]
            workflow.tasks = tasks
            self.session.saveWorkflow(workflow)
            self.xmltext = render_model(workflow)
    elif object=='link':
        if action in ["create","update"]:
            if action=="create":
                workflow_id = int(self.request.getfirst('workflow_id'))
                workflow = self.session.readWorkflow(workflow_id)
                ids = [int(link.id) for link in workflow.links]
                if ids:
                    id = max(ids)+1
                else:
                    id = 1
                link = Link()
                link.id = id
                workflow.links = workflow.links + [link]
            elif action=="update":
                workflow_id = int(self.request.getfirst('workflow_id'))
                link_id = int(self.request.getfirst('link_id'))
                workflow = self.session.readWorkflow(workflow_id)
                link = [l for l in workflow.links if int(l.id)==link_id][0]
            if self.request.has_key('from_parameter'):
                from_parameter = self.request.getfirst('from_parameter')
                link.from_parameter = from_parameter
            if self.request.has_key('from_task'):
                from_task = self.request.getfirst('from_task')
                link.from_task = from_task
            if self.request.has_key('to_parameter'):
                to_parameter = self.request.getfirst('to_parameter')
                link.to_parameter = to_parameter
            if self.request.has_key('to_task'):
                to_task = self.request.getfirst('to_task')
                link.to_task = to_task
            self.session.saveWorkflow(workflow)
            self.xmltext = render_model(link)
        elif action=="get":
            workflow_id = int(self.request.getfirst('workflow_id'))
            link_id = int(self.request.getfirst('link_id'))
            workflow = self.session.readWorkflow(workflow_id)
            link = [t for t in workflow.links if int(t.id)==link_id][0]
            self.xmltext = render_model(t)
        elif action=="delete":
            workflow_id = int(self.request.getfirst('workflow_id'))
            link_id = int(self.request.getfirst('link_id'))
            workflow = self.session.readWorkflow(workflow_id)
            links = [l for l in workflow.links if int(l.id)!=link_id]
            workflow.links = links
            self.session.saveWorkflow(workflow)
            self.xmltext = render_model(workflow)
    elif object=='parameter':
        if action in ["create","update"]:
            if action=="create":
                workflow_id = int(self.request.getfirst('workflow_id'))
                isout = self.request.getfirst('stream')=='output'
                workflow = self.session.readWorkflow(workflow_id)
                ids = [int(parameter.id) for parameter in workflow.parameters]
                if ids:
                    id = max(ids)+1
                else:
                    id = 1
                parameter = Parameter()
                parameter.id = id
                parameter.isout = isout
                workflow.parameters = workflow.parameters + [parameter]
            elif action=="update":
                workflow_id = int(self.request.getfirst('workflow_id'))
                parameter_id = int(self.request.getfirst('parameter_id'))
                workflow = self.session.readWorkflow(workflow_id)
                parameter = [p for p in workflow.parameters if int(p.id)==parameter_id][0]
            if self.request.has_key('name'):
                name = self.request.getfirst('name')
                parameter.name = name
            if self.request.has_key('prompt'):
                prompt = self.request.getfirst('prompt')
                parameter.prompt = prompt
            if self.request.has_key('example'):
                example = self.request.getfirst('example')
                parameter.example = example
            if self.request.has_key('datatype_class'):
                datatype_class = self.request.getfirst('datatype_class')
                parameter.type = (Type(),parameter.type) [parameter.type!=None]
                parameter.type.datatype = (Datatype(),parameter.type.datatype) [parameter.type.datatype!=None]
                parameter.type.datatype.class_name = datatype_class
            if self.request.has_key('datatype_superclass'):
                datatype_superclass = self.request.getfirst('datatype_superclass')
                parameter.type = (Type(),parameter.type) [parameter.type!=None]
                parameter.type.datatype = (Datatype(),parameter.type.datatype) [parameter.type.datatype!=None]
                parameter.type.datatype.superclass_name = datatype_superclass
            if self.request.has_key('biotype'):
                biotypes = self.request.getlist('biotype')
                parameter.biotypes = [Biotype(b) for b in biotypes]
            if self.request.has_key('example'):
                example = self.request.getfirst('example')
                parameter.example = example
            self.session.saveWorkflow(workflow)
            self.xmltext = render_model(parameter)
        elif action=="get":
            workflow_id = int(self.request.getfirst('workflow_id'))
            parameter_id = int(self.request.getfirst('parameter_id'))
            workflow = self.session.readWorkflow(workflow_id)
            parameter = [p for p in workflow.parameters if int(p.id)==parameter_id][0]
            self.xmltext = render_model(parameter)
        elif action=="delete":
            workflow_id = int(self.request.getfirst('workflow_id'))
            parameter_id = int(self.request.getfirst('parameter_id'))
            workflow = self.session.readWorkflow(workflow_id)
            parameters = [l for l in workflow.parameters if int(l.id)!=parameter_id]
            workflow.parameters = parameters
            self.session.saveWorkflow(workflow)
            self.xmltext = render_model(workflow)
    else:
        self.xmltext = "error"

mp = Parser()        

def render_model(e):
    return mp.tostring(e)

if __name__ == "__main__":
    mb_cgi.XMLCGI(processFunction=process,useSession=True)