package org.requirementsascode.builder;

import static org.requirementsascode.builder.FlowlessUserPart.flowlessOnPart;
import static org.requirementsascode.builder.FlowlessUserPart.flowlessUserPart;
import static org.requirementsascode.builder.StepPart.stepPartWithoutFlow;

import java.util.function.Supplier;

import org.requirementsascode.Condition;
import org.requirementsascode.ModelRunner;

public class FlowlessStepPart {
	private final StepPart stepPart;
	private final long flowlessStepCounter;

	private FlowlessStepPart(String stepName, UseCasePart useCasePart, Condition optionalCondition, long flowlessStepCounter) {
		this.stepPart = stepPartWithoutFlow(stepName, useCasePart, optionalCondition);
		this.flowlessStepCounter = flowlessStepCounter;
	}
	
	static FlowlessStepPart flowlessStepPart(String stepName, UseCasePart useCasePart, Condition optionalCondition, long flowlessStepCounter) {
		return new FlowlessStepPart(stepName, useCasePart, optionalCondition, flowlessStepCounter);
	}

	/**
	 * Defines the type of user commands that this step accepts. Commands of this
	 * type can cause a system reaction.
	 *
	 * <p>
	 * Given that the step's condition is true, the system reacts to objects that
	 * are instances of the specified class or instances of any direct or indirect
	 * subclass of the specified class.
	 *
	 * @param commandClass the class of commands the system reacts to in this step
	 * @param <T>          the type of the class
	 * @return the created user part of this step
	 */
	public <T> FlowlessUserPart<T> user(Class<T> commandClass) {
		FlowlessUserPart<T> flowlessUserPart = flowlessUserPart(commandClass, stepPart, flowlessStepCounter);
		return flowlessUserPart;
	}

	/**
	 * Defines the type of system event objects or exceptions that this step
	 * handles. Events of the specified type can cause a system reaction.
	 *
	 * <p>
	 * Given that the step's condition is true, the system reacts to objects that
	 * are instances of the specified class or instances of any direct or indirect
	 * subclass of the specified class.
	 *
	 * @param messageClass the class of messages the system reacts to
	 * @param <T>          the type of the class
	 * @return the created user part of this step
	 */
	public <T> FlowlessUserPart<T> on(Class<T> messageClass) {
		FlowlessUserPart<T> flowlessUserPart = flowlessOnPart(messageClass, stepPart, flowlessStepCounter);
		return flowlessUserPart;
	}

	/**
	 * Defines an "autonomous system reaction", meaning the system will react
	 * without needing a message provided via {@link ModelRunner#reactTo(Object)}.
	 *
	 * @param systemReaction the autonomous system reaction
	 * @return the created system part of this step
	 */
	public FlowlessSystemPart<ModelRunner> system(Runnable systemReaction) {
		FlowlessSystemPart<ModelRunner> flowlessSystemPart = user(ModelRunner.class).system(systemReaction);
		return flowlessSystemPart;
	}

	/**
	 * Defines an "autonomous system reaction", meaning the system will react
	 * without needing a message provided via {@link ModelRunner#reactTo(Object)}.
	 * After executing the system reaction, the runner will publish the returned
	 * event.
	 *
	 * @param systemReaction the autonomous system reaction, that returns a single
	 *                       event to be published.
	 * @return the created system part of this step
	 */
	public FlowlessSystemPart<ModelRunner> systemPublish(Supplier<?> systemReaction) {
		@SuppressWarnings("unchecked")
		FlowlessSystemPart<ModelRunner> flowlessSystemPart = user(ModelRunner.class).systemPublish(
			(Supplier<Object>) systemReaction);
		return flowlessSystemPart;
	}
}

@@ -301,24 +301,61 @@
 .Supplier;%0A%0A
+import org.requirementsascode.Actor;%0A
 import org.r
@@ -791,16 +791,186 @@
 ounter;%0A
+%09%09setDefaultActor(useCasePart);%0A%09%7D%0A%0A%09private void setDefaultActor(UseCasePart useCasePart) %7B%0A%09%09stepPart.getStep().setActors(new Actor%5B%5D %7BuseCasePart.getDefaultActor()%7D);%0A
 %09%7D%0A%09%0A%09st

Set the default actor in FlowlessStepPart