package pizzavolumecalculator.actor;

import static java.lang.Math.PI;

import java.util.function.Consumer;
import java.util.function.Supplier;

import org.requirementsascode.AbstractActor;
import org.requirementsascode.Condition;
import org.requirementsascode.Model;

import pizzavolumecalculator.actor.command.CalculateVolume;
import pizzavolumecalculator.actor.command.EnterHeight;
import pizzavolumecalculator.actor.command.EnterRadius;

public class PizzaVolumeCalculator extends AbstractActor {
  private int z;
  private int a;

  private Consumer<EnterRadius> saveRadius;
  private Consumer<EnterHeight> saveHeight;
  private Supplier<Double> calculateVolume;
  private Runnable throwIllegalRadiusException;
  private Runnable throwIllegalHeightException;
  private Condition isNegativeRadius;
  private Condition isNegativeHeight;

  public PizzaVolumeCalculator() {
    this.saveRadius = this::saveRadius;
    this.saveHeight = this::saveHeight;
    this.calculateVolume = this::calculateVolume;
    this.throwIllegalRadiusException = this::throwIllegalRadiusException;
    this.throwIllegalHeightException = this::throwIllegalHeightException;
    this.isNegativeRadius = this::isNegativeRadius;
    this.isNegativeHeight = this::isNegativeHeight;
  }

  @Override
  public Model behavior() {
    Model model = Model.builder()
      .useCase("Calculate Pizza Volume").basicFlow()
        .step("S1").user(EnterRadius.class).system(saveRadius)
        .step("S2").user(EnterHeight.class).system(saveHeight)
        .step("S3").user(CalculateVolume.class).systemPublish(calculateVolume)
        .step("S4").continuesAt("S1")

      .flow("Negative radius").after("S1").condition(isNegativeRadius)
        .step("S1a_1").system(throwIllegalRadiusException)

      .flow("Negative height").after("S2").condition(isNegativeHeight)
        .step("S2a_1").system(throwIllegalHeightException)

      .build();

    return model;
  }

  // system reactions
  private void saveRadius(EnterRadius enterRadius) {
    this.z = enterRadius.getRadius();
  }

  private void saveHeight(EnterHeight enterHeight) {
    this.a = enterHeight.getHeight();
  }

  private Double calculateVolume() {
    return PI * z * z * a;
  }

  private void throwIllegalRadiusException() {
    throw new IllegalArgumentException("Please specify a non-negative radius!");
  }

  private void throwIllegalHeightException() {
    throw new IllegalArgumentException("Please specify a non-negative height!");
  }

  // conditions
  private boolean isNegativeRadius() {
    return z < 0;
  }

  private boolean isNegativeHeight() {
    return a < 0;
  }
}
@@ -508,17 +508,17 @@
 ate int 
-z
+r
 ;%0A  priv
@@ -525,17 +525,17 @@
 ate int 
-a
+h
 ;%0A%0A  pri
@@ -2013,17 +2013,17 @@
    this.
-z
+r
  = enter
@@ -2109,17 +2109,17 @@
    this.
-a
+h
  = enter
@@ -2200,17 +2200,17 @@
 I * 
-z * z * a
+r * r * h
 ;%0A  
@@ -2544,17 +2544,17 @@
  return 
-z
+r
  %3C 0;%0A  
@@ -2606,17 +2606,17 @@
  return 
-a
+h
  %3C 0;%0A  

Make test more readable