"""Workflow for students.
"""
import grok
from hurry.workflow.workflow import Transition, WorkflowState, NullCondition
from hurry.workflow.interfaces import IWorkflowState, IWorkflowTransitionEvent
from waeup.sirp.interfaces import IObjectHistory, IWAeUPWorkflowInfo
from waeup.sirp.workflow import WAeUPWorkflow, WAeUPWorkflowInfo
from waeup.sirp.utils.helpers import get_current_principal
from waeup.sirp.students.interfaces import IStudent
from waeup.sirp.students.utils import set_returning_data

CREATED = 'created'
ADMITTED = 'admitted'
CLEARANCE = 'clearance started'
REQUESTED = 'clearance requested'
CLEARED = 'cleared'
PAID = 'school fee paid'
RETURNING = 'returning'
REGISTERED = 'courses registered'
VALIDATED = 'courses validated'

REGISTRATION_TRANSITIONS = (
    Transition(
        transition_id = 'create',
        title = 'Create student',
        source = None,
        condition = NullCondition,
        msg = 'Student record created',
        destination = CREATED),

    Transition(
        transition_id = 'admit',
        title = 'Admit student',
        msg = 'Student admitted',
        source = CREATED,
        destination = ADMITTED),

    Transition(
        transition_id = 'reset1',
        title = 'Reset student',
        msg = 'Student record reset',
        source = ADMITTED,
        destination = CREATED),

    Transition(
        transition_id = 'start_clearance',
        title = 'Start clearance',
        msg = 'Clearance started',
        source = ADMITTED,
        destination = CLEARANCE),

    Transition(
        transition_id = 'reset2',
        title = 'Reset to admitted',
        msg = 'Student record reset to admitted',
        source = CLEARANCE,
        destination = ADMITTED),

    Transition(
        transition_id = 'request_clearance',
        title = 'Request clearance',
        msg = 'Clearance requested',
        source = CLEARANCE,
        destination = REQUESTED),

    Transition(
        transition_id = 'reset3',
        title = 'Reset to clearance',
        msg = 'Student record reset to clearance',
        source = REQUESTED,
        destination = CLEARANCE),

    Transition(
        transition_id = 'clear',
        title = 'Clear student',
        msg = 'Cleared',
        source = REQUESTED,
        destination = CLEARED),

    Transition(
        transition_id = 'reset4',
        title = 'Reset to clearance',
        msg = 'Student record reset to clearance',
        source = CLEARED,
        destination = CLEARANCE),

    Transition(
        transition_id = 'pay_first_school_fee',
        title = 'Pay school fee',
        msg = 'School fee paid',
        source = CLEARED,
        destination = PAID),

    Transition(
        transition_id = 'reset5',
        title = 'Reset to cleared',
        msg = 'Student record reset to cleared',
        source = PAID,
        destination = CLEARED),

    Transition(
        transition_id = 'pay_school_fee',
        title = 'Pay school fee',
        msg = 'School fee paid',
        source = RETURNING,
        destination = PAID),

    Transition(
        transition_id = 'reset6',
        title = 'Reset to returning',
        msg = 'Student record reset to returning',
        source = PAID,
        destination = RETURNING),

    Transition(
        transition_id = 'register_courses',
        title = 'Register courses',
        msg = 'Courses registered',
        source = PAID,
        destination = REGISTERED),

    Transition(
        transition_id = 'reset7',
        title = 'Reset to paid',
        msg = 'Student record reset to paid',
        source = REGISTERED,
        destination = PAID),

    Transition(
        transition_id = 'validate_courses',
        title = 'Validate courses',
        msg = 'Courses validated',
        source = REGISTERED,
        destination = VALIDATED),

    Transition(
        transition_id = 'reset8',
        title = 'Reset to paid',
        msg = 'Student record reset to paid',
        source = VALIDATED,
        destination = PAID),

    Transition(
        transition_id = 'return',
        title = 'Return',
        msg = 'Returned',
        source = VALIDATED,
        destination = RETURNING),

    Transition(
        transition_id = 'reset9',
        title = 'Reset to validated',
        msg = 'Student record reset to validated',
        source = RETURNING,
        destination = VALIDATED),
    )

LOCK_CLEARANCE_TRANS = ('reset2', 'request_clearance')
UNLOCK_CLEARANCE_TRANS = ('reset3', 'reset4', 'start_clearance')

registration_workflow = WAeUPWorkflow(REGISTRATION_TRANSITIONS)

class RegistrationWorkflowState(WorkflowState, grok.Adapter):
    """An adapter to adapt Student objects to workflow states.
    """
    grok.context(IStudent)
    grok.provides(IWorkflowState)

    state_key = 'wf.registration.state'
    state_id = 'wf.registration.id'

class RegistrationWorkflowInfo(WAeUPWorkflowInfo, grok.Adapter):
    """Adapter to adapt Student objects to workflow info objects.
    """
    grok.context(IStudent)
    grok.provides(IWAeUPWorkflowInfo)

    def __init__(self, context):
        self.context = context
        self.wf = registration_workflow

@grok.subscribe(IStudent, IWorkflowTransitionEvent)
def handle_student_transition_event(obj, event):
    """Append message to student history and log file when transition happened.
    """
    msg = '%s' % event.transition.user_data['msg']
    history = IObjectHistory(obj)
    history.addMessage(msg)
    if event.transition.transition_id in LOCK_CLEARANCE_TRANS:
        obj.clearance_locked = True
    if event.transition.transition_id in UNLOCK_CLEARANCE_TRANS:
        obj.clearance_locked = False
    # Student data don't change after first-time payment
    if event.transition.transition_id == 'pay_first_school_fee':
        pass
    # School fee payment of returning students triggers the change of
    # current session, current level, and current verdict
    if event.transition.transition_id == 'pay_school_fee':
        set_returning_data(obj)
    # In some tests we don't have a students container or a user
    try:
        user = get_current_principal()
        students_container = grok.getSite()['students']
        students_container.logger.info('%s - %s - %s' % (user.id,obj.student_id,msg))
    except (TypeError, AttributeError):
        pass
    return
