from .domain import TaskState


class InvalidTransition(ValueError):
    pass


TRANSITIONS = {
    TaskState.INIT: {"planning_started": TaskState.PLAN},
    TaskState.PLAN: {"plan_drafted": TaskState.PLAN_REVIEW},
    TaskState.PLAN_REVIEW: {"plan_approved": TaskState.IMPLEMENT, "plan_rejected": TaskState.PLAN},
    TaskState.IMPLEMENT: {"implementation_finished": TaskState.TEST, "replan_requested": TaskState.PLAN},
    TaskState.TEST: {"tests_passed": TaskState.REVIEW, "tests_failed": TaskState.FIX},
    TaskState.REVIEW: {"review_passed": TaskState.FINAL_VERIFY, "changes_required": TaskState.FIX},
    TaskState.FIX: {"fix_finished": TaskState.TEST},
    TaskState.FINAL_VERIFY: {"verified": TaskState.DONE, "changes_required": TaskState.FIX},
}

#: Every non-terminal state may fail closed into NEEDS_HUMAN.
for _state, _events in TRANSITIONS.items():
    _events["needs_human"] = TaskState.NEEDS_HUMAN


def next_state(current: TaskState, event: str) -> TaskState:
    try:
        return TRANSITIONS[current][event]
    except KeyError as error:
        raise InvalidTransition(f"Cannot apply {event!r} in {current.value}") from error
