package com.spring.statemachine.sample.example;

import com.spring.statemachine.sample.Events;
import com.spring.statemachine.sample.States;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.config.configurers.StateConfigurer;
import org.springframework.stereotype.Component;

@Component
@EnableStateMachine(name = "1")
public class HistoryStateMachine extends EnumStateMachineConfigurerAdapter<States, Events> {

    @Override
    public void configure(StateMachineStateConfigurer<States, Events> states)
            throws Exception {
        states
                .withStates()
                .initial(States.S1)
                .state(States.S2)
                .and()
                .withStates()
                .parent(States.S2)
                .initial(States.S2I)
                .state(States.S21)
                .state(States.S22)
                .history(States.S2H, StateConfigurer.History.SHALLOW).
                and()
                .withStates()
                .parent(States.S22)
                .initial(States.S22I)
                .state(States.S221)
                .state(States.S222);
    }

    @Override
    public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
            throws Exception {
        transitions
                .withHistory()
                .source(States.S2H)
                .target(States.S22)
                .and()
                .withExternal()
                .source(States.S1)
                .target(States.S2)
                .event(Events.E2)
                .and()
                .withExternal()
                .source(States.S2)
                .target(States.S1)
                .event(Events.E1)
                .and()
                .withExternal()
                .source(States.S2)
                .target(States.S21)
                .event(Events.E21)
                .and()
                .withExternal()
                .source(States.S21)
                .target(States.S22)
                .event(Events.E22)
                .and()
                .withExternal()
                .source(States.S2)
                .target(States.S2H)
                .event(Events.E2H)
                .and()
                .withExternal()
                .source(States.S22)
                .target(States.S221)
                .event(Events.E221);
    }

}