package helloworld;

import static org.requirementsascode.UseCaseModelBuilder.newBuilder;

import org.requirementsascode.UseCaseModel;
import org.requirementsascode.UseCaseModelBuilder;
import org.requirementsascode.UseCaseModelRunner;

public class HelloWorld05_EnterNameAndAgeWithValidationExample extends AbstractHelloWorldExample{
	private static final Class<EnterText> ENTER_FIRST_NAME = EnterText.class;
	private static final Class<EnterText> ENTER_AGE = EnterText.class;
	private static final Class<NumberFormatException> NON_NUMERICAL_AGE = NumberFormatException.class;
	
	private static final String S2 = "S2";	
	private static final String S4 = "S4";	
	private static final String S5 = "S5";
	
	private static final int MIN_AGE = 5;
	private static final int MAX_AGE = 130;
	
	private String firstName;
	private int age;
	
	public UseCaseModel buildWith(UseCaseModelBuilder modelBuilder) {
		UseCaseModel useCaseModel = 
			modelBuilder.useCase("Get greeted")
				.basicFlow()
					.step("S1").system(this::promptUserToEnterFirstName)
					.step(S2).user(ENTER_FIRST_NAME).system(this::saveFirstName)
					.step("S3").system(this::promptUserToEnterAge)
					.step(S4).user(ENTER_AGE).system(this::saveAge)
					.step(S5).system(this::greetUserWithFirstNameAndAge)
					.step("S6").system(this::stopSystem)
						
				.flow("Handle out-of-bounds age").insteadOf(S5).when(this::ageIsOutOfBounds)
					.step("S5a_1").system(this::informUserAboutOutOfBoundsAge)
					.step("S5a_2").continueAfter(S2)
						
				.flow("Handle non-numerical age").insteadOf(S5)
					.step("S5b_1").handle(NON_NUMERICAL_AGE).system(this::informUserAboutNonNumericalAge)
					.step("S5b_2").continueAfter(S2)
			.build();
		return useCaseModel;
	}

	private void promptUserToEnterFirstName(UseCaseModelRunner runner) {
		System.out.print("Please enter your first name: ");
	}
	
	private void promptUserToEnterAge(UseCaseModelRunner runner) {
		System.out.print("Please enter your age: ");
	}

	private void saveFirstName(EnterText enterText) {
		firstName = enterText.text;
	}
	
	private void saveAge(EnterText enterText) {
		age = Integer.parseInt(enterText.text);
	}
	
	private void greetUserWithFirstNameAndAge(UseCaseModelRunner runner) {
		System.out.println("Hello, " + firstName + " (" + age + ").");
	}
	
	private boolean ageIsOutOfBounds(UseCaseModelRunner runner) {
		return age < MIN_AGE || age > MAX_AGE;
	}
	
	private void informUserAboutOutOfBoundsAge(UseCaseModelRunner runner) {
		System.out.println("Please enter your real age, between " + MIN_AGE + " and " + MAX_AGE);
	}
	
	private void informUserAboutNonNumericalAge(NumberFormatException exception) {
		System.out.println("You entered a non-numerical age.");
	}
	
	public static void main(String[] args){		
		HelloWorld05_EnterNameAndAgeWithValidationExample example = new HelloWorld05_EnterNameAndAgeWithValidationExample();
		example.start(); 
	}

	private void start() {
		UseCaseModelRunner useCaseModelRunner = new UseCaseModelRunner();
		UseCaseModel useCaseModel = buildWith(newBuilder());
		
		useCaseModelRunner.run(useCaseModel);			
		while(!systemStopped())
			useCaseModelRunner.reactTo(enterText());	
		exitSystem();	
	}
}

@@ -576,131 +576,8 @@
 s;%0A%09
-%0A%09private static final String S2 = %22S2%22;%09%0A%09private static final String S4 = %22S4%22;%09%0A%09private static final String S5 = %22S5%22;%0A
 %09%0A%09p
@@ -926,18 +926,20 @@
 %09%09.step(
+%22
 S2
+%22
 ).user(E
@@ -1050,10 +1050,12 @@
 tep(
+%22
 S4
+%22
 ).us
@@ -1101,18 +1101,20 @@
 %09%09.step(
+%22
 S5
+%22
 ).system
@@ -1247,18 +1247,20 @@
 steadOf(
+%22
 S5
+%22
 ).when(t
@@ -1376,26 +1376,28 @@
 ntinueAfter(
+%22
 S2
+%22
 )%0A%09%09%09%09%09%09%0A%09%09%09
@@ -1441,18 +1441,20 @@
 steadOf(
+%22
 S5
+%22
 )%0A%09%09%09%09%09.
@@ -1572,18 +1572,20 @@
 ueAfter(
+%22
 S2
+%22
 )%0A%09%09%09.bu

Use strings instead of string constants