from cymem.cymem cimport Pool

from ...strings cimport StringStore
from ...structs cimport TokenC
from ...training.example cimport Example
from ...typedefs cimport attr_t, weight_t
from ._state cimport StateC
from .stateclass cimport StateClass


cdef struct Transition:
    int clas
    int move
    attr_t label

    weight_t score

    bint (*is_valid)(const StateC* state, attr_t label) noexcept nogil
    weight_t (*get_cost)(const StateC* state, const void* gold, attr_t label) noexcept nogil
    int (*do)(StateC* state, attr_t label) noexcept nogil


ctypedef weight_t (*get_cost_func_t)(
    const StateC* state, const void* gold, attr_tlabel
) noexcept nogil
ctypedef weight_t (*move_cost_func_t)(
        const StateC* state, const void* gold
) noexcept nogil
ctypedef weight_t (*label_cost_func_t)(
    const StateC* state, const void* gold, attr_t label
) noexcept nogil

ctypedef int (*do_func_t)(StateC* state, attr_t label) noexcept nogil

ctypedef void* (*init_state_t)(Pool mem, int length, void* tokens) except NULL

ctypedef int (*del_state_t)(Pool mem, void* state, void* extra_args) except -1

cdef class TransitionSystem:
    cdef Pool mem
    cdef StringStore strings
    cdef Transition* c
    cdef readonly int n_moves
    cdef int _size
    cdef public attr_t root_label
    cdef public freqs
    cdef public object labels
    cdef public object cfg
    cdef init_state_t init_beam_state
    cdef del_state_t del_beam_state

    cdef Transition lookup_transition(self, object name) except *

    cdef Transition init_transition(self, int clas, int move, attr_t label) except *

    cdef int set_valid(self, int* output, const StateC* st) noexcept nogil

    cdef int set_costs(self, int* is_valid, weight_t* costs,
                       const StateC* state, gold) except -1
