package io.github.theangrydev.businessflows;

import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;

import static java.lang.String.format;

abstract class BusinessFlow<Sad, Happy, Actual> {

    final Sad sad;
    final Happy happy;
    final Exception technicalFailure;

    BusinessFlow(Sad sad, Happy happy, Exception technicalFailure) {
        this.sad = sad;
        this.happy = happy;
        this.technicalFailure = technicalFailure;
    }

    public <Result> Result join(Function<Sad, Result> sadJoiner, Function<Happy, Result> happyJoiner, Function<Exception, Result> technicalFailureJoiner) {
        if (happy != null) {
            return happyJoiner.apply(happy);
        } else if (sad != null) {
            return sadJoiner.apply(sad);
        } else if (technicalFailure != null) {
            return technicalFailureJoiner.apply(technicalFailure);
        } else {
            throw new IllegalStateException("Impossible scenario. There must always be a happy or sad or technical failure.");
        }
    }

    public abstract Optional<Actual> toOptional();

    public Actual get() {
        return toOptional().orElseThrow(() -> new RuntimeException(format("Not present. Happy path was '%s'. Sad path was '%s'. Exception was '%s'.", happy, sad, technicalFailure)));
    }

    public Actual orElse(Actual alternative) {
        return toOptional().orElse(alternative);
    }

    public Actual orElseGet(Supplier<Actual> alternativeSupplier) {
        return toOptional().orElseGet(alternativeSupplier);
    }

    public <X extends Throwable> Actual orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
        return toOptional().orElseThrow(exceptionSupplier);
    }

    public TechnicalFailure<Sad, Happy> ifTechnicalFailure() {
        return new TechnicalFailure<>(sad, happy, technicalFailure);
    }

    public SadPath<Sad, Happy> ifSad() {
        return new SadPath<>(sad, happy, technicalFailure);
    }

    public HappyPath<Sad, Happy> ifHappy() {
        return new HappyPath<>(sad, happy, technicalFailure);
    }
}

@@ -179,16 +179,23 @@
 ormat;%0A%0A
+public 
 abstract
@@ -226,22 +226,20 @@
  Happy, 
-Actual
+Bias
 %3E %7B%0A%0A   
@@ -1103,22 +1103,20 @@
 ptional%3C
-Actual
+Bias
 %3E toOpti
@@ -1135,22 +1135,20 @@
  public 
-Actual
+Bias
  get() %7B
@@ -1353,22 +1353,20 @@
 lic 
-Actual
+Bias
  orElse(
 Actu
@@ -1361,22 +1361,20 @@
  orElse(
-Actual
+Bias
  alterna
@@ -1448,22 +1448,20 @@
  public 
-Actual
+Bias
  orElseG
@@ -1472,22 +1472,20 @@
 upplier%3C
-Actual
+Bias
 %3E altern
@@ -1605,14 +1605,12 @@
 le%3E 
-Actual
+Bias
  orE

Rename Actual to Bias in BusinessFlow.java