package net.zerobuilder.compiler.generate;

import net.zerobuilder.compiler.generate.DtoBeanGoal.BeanGoalContext;
import net.zerobuilder.compiler.generate.DtoGoalContext.AbstractGoalContext;
import net.zerobuilder.compiler.generate.DtoRegularGoal.SimpleRegularGoalContext;
import net.zerobuilder.compiler.generate.DtoStep.AbstractStep;

import java.util.List;
import java.util.function.Function;

public final class DtoSimpleGoal {

  public interface SimpleGoal {
    <R> R acceptSimple(SimpleGoalCases<R> cases);
  }

  interface SimpleGoalCases<R> {
    R regular(SimpleRegularGoalContext regular);
    R bean(BeanGoalContext bean);
  }

  static <R> Function<SimpleGoal, R> asFunction(SimpleGoalCases<R> cases) {
    return goal -> goal.acceptSimple(cases);
  }

  public static <R> Function<SimpleGoal, R> simpleGoalCases(
      Function<? super SimpleRegularGoalContext, ? extends R> regularFunction,
      Function<? super BeanGoalContext, ? extends R> beanFunction) {
    return asFunction(new SimpleGoalCases<R>() {
      @Override
      public R regular(SimpleRegularGoalContext regular) {
        return regularFunction.apply(regular);
      }
      @Override
      public R bean(BeanGoalContext bean) {
        return beanFunction.apply(bean);
      }
    });
  }

  static <R> Function<SimpleGoal, R> restrict(Function<AbstractGoalContext, R> function) {
    return simpleGoalCases(
        regular -> function.apply(regular),
        bean -> function.apply(bean)
    );
  }

  public static final Function<SimpleGoal, DtoContext.BuildersContext> context =
      restrict(AbstractGoalContext::context);

  public static final Function<SimpleGoal, String> name =
      simpleGoalCases(
          simpleRegularGoalContext -> simpleRegularGoalContext.regularDetails().name,
          bean -> bean.details.name);

  public static final Function<SimpleGoal, List<? extends AbstractStep>> abstractSteps =
      restrict(AbstractGoalContext::steps);

  private DtoSimpleGoal() {
    throw new UnsupportedOperationException("no instances");
  }
}

@@ -111,85 +111,8 @@
 xt;%0A
-import net.zerobuilder.compiler.generate.DtoGoalContext.AbstractGoalContext;%0A
 impo
@@ -313,16 +313,71 @@
 ction;%0A%0A
+import static java.util.Collections.unmodifiableList;%0A%0A
 public f
@@ -1246,34 +1246,43 @@
  %7D);%0A  %7D%0A%0A  
+public 
 static 
-%3CR%3E
+final
  Function%3CSi
@@ -1295,303 +1295,285 @@
 al, 
-R%3E restrict(Function%3CAbstractGoalContext, R%3E function) %7B%0A    return simpleGoalCases(%0A        regular -%3E function.apply(regular),%0A        bean -%3E function.apply(bean)%0A    );%0A  %7D%0A%0A  public static final Function%3CSimpleGoal, DtoContext.BuildersContext%3E context =%0A      restrict(AbstractGoalContext::
+DtoContext.BuildersContext%3E context =%0A      simpleGoalCases(%0A          DtoRegularGoal.regularGoalContextCases(%0A              constructor -%3E constructor.context,%0A              method -%3E method.context,%0A              staticMethod -%3E staticMethod.context),%0A          bean -%3E bean.
 cont
@@ -1670,23 +1670,32 @@
         
-simpleR
+DtoRegularGoal.r
 egularGo
@@ -1707,58 +1707,171 @@
 text
- -%3E simpleRegularGoalContext.regularD
+Cases(%0A              constructor -%3E constructor.details.name,%0A              method -%3E method.details.name,%0A              staticMethod -%3E staticMethod.d
 etails
-()
 .name
+)
 ,%0A  
@@ -2006,44 +2006,259 @@
     
-restrict(AbstractGoalContext::
+simpleGoalCases(%0A          DtoRegularGoal.regularGoalContextCases(%0A              constructor -%3E constructor.steps,%0A              method -%3E method.steps,%0A              staticMethod -%3E staticMethod.steps),%0A          bean -%3E unmodifiableList(bean.
 steps)
+)
 ;%0A%0A 

remove DtoSimpleGoal.restrict