import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Anastasiya Solodkaya.
 */
public class CountedLoopProposal10 {
    public static void main(String[] args) throws Throwable {
        MethodHandle methodHandle0 = MethodHandles.countedLoop(
                MethodSet.iteration(int.class, List.class),
                null,
                MethodSet.body(String.class, int.class, String.class));
        System.out.println("methodHandle0.type() = " + methodHandle0.type());
        methodHandle0.invoke(new ArrayList<String>());
    }

    static class MethodSet {
        static int iterationInt(List<String> loopParams) {
            return 10;
        }

        static String bodyString(int counter, String localParam) {
            System.out.println("localParam = " + localParam);
            return "local" + counter;
        }

        static MethodHandle body(Class returnType, Class... params) {
            return findStatic("body", returnType, params);
        }

        static MethodHandle iteration(Class returnType, Class... params) {
            return findStatic("iteration", returnType, params);
        }

        private static MethodHandle findStatic(String prefix, Class returnType, Class[] params) {
            try {
                String simpleName = returnType.getSimpleName();
                simpleName = simpleName.substring(0, 1).toUpperCase() + simpleName.substring(1);
                return MethodHandles.lookup().findStatic(MethodSet.class, prefix + simpleName, MethodType.methodType(returnType, params));
            } catch (NoSuchMethodException | IllegalAccessException e) {
                e.printStackTrace();
                return null;
            }
        }


    }

}
