package io.ghostwriter;


import io.ghostwriter.test.MessageSequenceAsserter;
import io.ghostwriter.test.Parameter;
import io.ghostwriter.test.TestBase;
import org.junit.Ignore;
import org.junit.Test;

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


public class LambdaTest extends TestBase {

    @Ignore
    public void testEntering() {
        fetchedPreparedInMemoryTracer();
        Function<Integer, String> lambda = (val) -> String.valueOf(val);

        lambda.apply(123);

        MessageSequenceAsserter.messageSequence()
                .entering("testEntering: (val)->", new Parameter<>("val", 123))
                // FIXME(snorbi07): enable after Lambda support fix
                //.returning("testEntering: (val)->", "123")
                .exiting("testEntering: (val)->");
    }

    @Test
    @Ignore
    public void testBlockBasedLambdaSupport() {
        Function<Integer, String> lambda = (val) -> {
            Integer newVal = val + 1;
            String str = String.valueOf(newVal);
            return str;
        };

        final InMemoryTracer inMemoryTracer = fetchedPreparedInMemoryTracer();
        inMemoryTracer.clearMessages();
        inMemoryTracer.enableValueChangeTracking();

        lambda.apply(123);

        MessageSequenceAsserter.messageSequence()
                .entering("testBlockBasedLambdaSupport: (val)->", new Parameter<>("val", 123))
                .valueChange("testBlockBasedLambdaSupport: (val)->", "newVal", 124)
                .valueChange("testBlockBasedLambdaSupport: (val)->", "str", "124")
                // FIXME(snorbi07): enable after Lambda support fix
                //.returning("testBlockBasedLambdaSupport: (val)->", "124")
                .exiting("testBlockBasedLambdaSupport: (val)->")
                .empty();
    }

    @Test
    @Ignore
    public void testNestedLambdaSupport() {
        Function<Integer, Function<Integer, Integer>> adder = (base) -> (val) -> base + val;

        final InMemoryTracer inMemoryTracer = fetchedPreparedInMemoryTracer();
        inMemoryTracer.clearMessages();
        inMemoryTracer.enableValueChangeTracking();

        adder.apply(16).apply(1);

        MessageSequenceAsserter.messageSequence()
                .entering("testNestedLambdaSupport: (base)->", new Parameter<>("base", 16))
                .any() // returning testNestedLambdaSupport: (base)-> ... comparing lambdas is not supported
                .exiting("testNestedLambdaSupport: (base)->")
                .entering("testNestedLambdaSupport: (val)->", new Parameter<>("val", 1))
                // FIXME(snorbi07): enable after Lambda support fix
                //.returning("testNestedLambdaSupport: (val)->", 17)
                .exiting("testNestedLambdaSupport: (val)->");
    }

    public <T> List<List<T>> testLambdaTypeInference() {
        java.util.function.Supplier<List<List<T>>> someCollectionSupplier;
        someCollectionSupplier = Collections::emptyList;
        return someCollectionSupplier.get();
    }

    // TODO: test this scoping
    // TODO: test class scoping
    // TODO: test lambda properties (not in a method context, is the generated name correct?)

}

@@ -225,16 +225,42 @@
 ctions;%0A
+import java.util.HashMap;%0A
 import j
@@ -304,19 +304,98 @@
 ion.
-Function;%0A%0A
+Consumer;%0Aimport java.util.function.Function;%0Aimport java.util.stream.Collector;%0A%0A%0A@Ignore
 %0Apub
@@ -436,30 +436,28 @@
 ase %7B%0A%0A    @
-Ignore
+Test
 %0A    public 
@@ -944,36 +944,24 @@
 %0A%0A    @Test%0A
-    @Ignore%0A
     public v
@@ -1941,20 +1941,8 @@
 est%0A
-    @Ignore%0A
     
@@ -2424,16 +2424,85 @@
 %22, 16))%0A
+%09    // FIXME(snorbi07): commented out until lambda support is fixed%0A
         
@@ -2501,24 +2501,26 @@
             
+//
     .any() /
@@ -3213,157 +3213,1308 @@
  // 
-TODO: test this s
+NOTE(snorbi07): for now this is just a 
 co
+m
 pi
-ng%0A    // TODO: test class scoping%0A    // TODO: test lambda properties (not in a method context, is the generated name correct?)
+lation check... if something is wrong it will fail to compile%0A    public static final class Item %7B%0A        private final double size;%0A        private final double value;%0A%0A        private Item(final double size, final double value) %7B%0A            this.size = size;%0A            this.value = value;%0A        %7D%0A%0A        public double getSize() %7B%0A            return size;%0A        %7D%0A%0A        public double getValue() %7B%0A            return value;%0A        %7D%0A%0A        private static Collector%3CItem, ?, Item%3E toSum() %7B%0A            return Collector.of(%0A                    () -%3E new double%5B2%5D,%0A                    (a, b) -%3E %7B%0A                        a%5B0%5D += b.getSize();%0A                        a%5B1%5D += b.getValue();%0A                    %7D,%0A                    (a, b) -%3E %7B%0A                        a%5B0%5D += b%5B0%5D;%0A                        a%5B1%5D += b%5B1%5D;%0A                        return a;%0A                    %7D,%0A                    r -%3E new Item(r%5B0%5D, r%5B1%5D)%0A            );%0A        %7D%0A    %7D%0A%0A    // NOTE(snorbi07): for now this is just a compilation check... if something is wrong it will fail to compile%0A    static public %3CK%3E void MYYYforEach(Consumer%3C? super K%3E action) %7B%0A        HashMap%3CK, Integer%3E map = new HashMap%3C%3E();%0A        map.forEach((k, v) -%3E action.accept(k));%0A    %7D
 %0A%0A%7D%0A

disable unit test for lambda support. we still rely on tets compilation based verification though...