# -*- coding: utf-8 -*-
"""
State tracking functionality for django models
"""
import inspect
from collections import namedtuple
from functools import wraps

from django.db import models
from django.db.models.signals import class_prepared
from django.utils.functional import curry
from django_fsm.signals import pre_transition, post_transition


__all__ = ["TransitionNotAllowed", "FSMFieldMixin", "FSMField",
           'FSMIntegerField', 'FSMKeyField', 'transition', 'can_proceed']


# South support; see http://south.aeracode.org/docs/tutorial/part4.html#simple-inheritance
try:
    from south.modelsinspector import add_introspection_rules
except ImportError:
    pass
else:
    add_introspection_rules([], [r"^django_fsm\.FSMField"])
    add_introspection_rules([], [r"^django_fsm\.FSMIntegerField"])
    add_introspection_rules([], [r"^django_fsm\.FSMKeyField"])


class TransitionNotAllowed(Exception):
    """Raise when a transition is not allowed"""


Transition = namedtuple('Transition', ['name', 'source', 'target', 'conditions', 'method'])


def get_available_FIELD_transitions(instance, field):
    curr_state = field.get_state(instance)
    transitions = field.transitions[instance.__class__]

    for name, transition in transitions.items():
        meta = transition._django_fsm

        for state in [curr_state, '*']:
            if state in meta.transitions:
                target, conditions = meta.transitions[state]
                if all(map(lambda condition: condition(instance), conditions)):
                    yield Transition(
                        name=name,
                        source=state,
                        target=target,
                        conditions=conditions,