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

/**
 * @author Anastasiya Solodkaya.
 */
public class CountedLoopProposal6 {
    public static void main(String[] args) {
        run(int.class);
        run(Object.class);
        run(List.class);
    }

    private static void run(Class returnType) {
        try {
            MethodHandle methodHandle = MethodHandles.countedLoop(MethodHandles.constant(int.class, 13), null, MethodSet.body(returnType, int.class, String.class));
            System.out.println(methodHandle.type());
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }

    }

    static class MethodSet {
        static String bodyString(int counter, String v) {
            return "";
        }

        static void bodyVoid(int counter, String v) {
        }

        static Object bodyObject(int counter, String v) {
            return null;
        }

        static List<String> bodyList(int counter, String v) {
            return null;
        }

        static int bodyInt(int counter, String v) {
            return 0;
        }

        static MethodHandle body(Class returnType, Class... params) {
            return findStatic("body", 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;
            }
        }


    }

}
