"""Workflows used in the WAeUP SRP portal.
"""
import grok
from hurry.workflow.workflow import Transition, Workflow, WorkflowVersions
from hurry.workflow.workflow import WorkflowInfo, WorkflowState, NullCondition
from hurry.workflow.interfaces import MANUAL, AUTOMATIC, SYSTEM
from hurry.workflow.interfaces import IWorkflow, IWorkflowState, IWorkflowInfo
from hurry.workflow.interfaces import IWorkflowVersions
from waeup.sirp.interfaces import IWAeUPObject

UNCHECKED = 'unchecked'
CHECKED = 'checked'

def create_workflow():
    init_transition = Transition(
        transition_id = 'init',
        title = 'Initialize',
        source = None,
        condition = NullCondition,
        destination = UNCHECKED)

    check_transition = Transition(
        transition_id = 'check',
        title = 'Check',
        source = UNCHECKED,
        destination = CHECKED)

    final_transition = Transition(
        transition_id = 'finalize',
        title = 'Delete',
        source = CHECKED,
        destination = None)

    return [init_transition, check_transition, final_transition]


class WAeUPWorkflow(Workflow):
    """A hurry.workflow Workflow with more appropriate error messages.
    """
    grok.provides(IWorkflow)
    def __init__(self):
        super(Workflow, self).__init__()
        self.refresh(create_workflow())

    def getTransition(self, source, transition_id):
        from hurry.workflow.interfaces import\
            InvalidTransitionError, ConditionFailedError

        transition = self._id_transitions[transition_id]
        if transition.source != source:
            raise InvalidTransitionError(
                "Transition '%s' requires '%s' as source state (is: '%s')" % (
                    transition_id, transition.source, source))
        return transition


class WorkflowNullVersions(WorkflowVersions):
    """A workflow versions manager that does not handle versions.

    Sounds odd, but the default implementation of
    :class:`hurry.workflow.workflow.WorkflowVersions` is a base
    implementation that raises :exc:`NotImplemented` exceptions for
    most of the methods defined below.

    If we want to register a versionless workflow, an utility
    implementing IWorkflowVersions is looked up nevertheless by
    WorkflowInfo and WorkflowState components so we **have** to
    provide workflow versions, even if we do not support versioned
    workflows.

    This implementation returns empty result sets for any requests,
    but does not raise :exc:`NotImplemented`.
    """
    def getVersions(self, state, id):
        return []

    def getVersionsWithAutomaticTransitions(self):
        return []

    def hasVersion(self, id, state):
        return False

    def hasVersionId(self, id):
        return False

# Register global utilities for workflows and workflow versions...
grok.global_utility(WAeUPWorkflow, IWorkflow)
grok.global_utility(WorkflowNullVersions, IWorkflowVersions)

class WorkflowState(grok.Adapter, WorkflowState):
    """An adapter to adapt WAeUP objects to workflow states.
    """
    grok.context(IWAeUPObject)
    grok.provides(IWorkflowState)
    
class WorkflowInfo(grok.Adapter, WorkflowInfo):
    """Adapter to adapt WAeUP objects to workflow info objects.
    """
    grok.context(IWAeUPObject)
    grok.provides(IWorkflowInfo)
