package com.github.alkedr.matchers.reporting;

import com.github.alkedr.matchers.reporting.reporters.HtmlReporter;
import org.hamcrest.Matcher;
import org.junit.Test;

import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static ch.lambdaj.Lambda.on;
import static com.github.alkedr.matchers.reporting.ValueExtractingMatcher.*;
import static com.github.alkedr.matchers.reporting.extractors.map.ValueFromMapExtractor.valueOfKey;
import static com.github.alkedr.matchers.reporting.extractors.object.FieldExtractor.field;
import static com.github.alkedr.matchers.reporting.extractors.object.LambdajArgumentExtractor.resultOf;
import static org.hamcrest.core.Is.is;

@SuppressWarnings("JUnitTestMethodWithNoAssertions")
public class HtmlReporterTest {
    @Test
    public void fastReportsTest() throws IOException {
        try (FileWriter fileWriter = new FileWriter("example-report.html")) {
            fileWriter.write(new HtmlReporter().report(veryComplexBeanMatcher().getReport(new VeryComplexBean())));
        }
    }


    // объекты, списки, мапы
    // извлечённые-непроверенные, извлечённые-проверенные-правильные и извлечённые-проверенные-неправильные, неизвлечённые с разными ошибками
    // только простые проверки, только сложные проверки, оба вида проверок



    private static ReportingMatcher<VeryComplexBean> veryComplexBeanMatcher() {
        map(Integer.class, Object.class)
                .checkThat(valueOfKey(1), is(1))
                .checkThat(valueOfKey(1), is(""))
                ;

        return object(VeryComplexBean.class)
                .checkThat(field(VeryComplexBean.class, "correctField"), correctComplexBean())
                .checkThat(field(VeryComplexBean.class, "incorrectField"), incorrectComplexBean())
                .checkThat(field(VeryComplexBean.class, "uncheckedField"), beanWithGetters(Object.class))
                ;
    }

    private static Matcher<ComplexBean> correctComplexBean() {
        return complexBean("3");
    }

    private static Matcher<ComplexBean> incorrectComplexBean() {
        return complexBean("4");
    }

    private static Matcher<ComplexBean> complexBean(String expectedStringPropertyValue) {
        ComplexBean on = on(ComplexBean.class);
        return beanWithGetters(ComplexBean.class)
                .checkThat(resultOf(on.isBooleanField()), is(false))
                .checkThat(resultOf(on.getIntField()), is(1))
                .checkThat(resultOf(on.getLongField()), is(2L))
                .checkThat(resultOf(on.getStringField()), is(expectedStringPropertyValue))
                ;
    }

    private static class VeryComplexBean {
        private final ComplexBean correctField = new ComplexBean();
        private final ComplexBean incorrectField = new ComplexBean();
        private final ComplexBean uncheckedField = new ComplexBean();
        private final Map<Object, String> map = new HashMap<>();
        private final List<Double> list = new ArrayList<>();

        private VeryComplexBean() {
            map.put(1, "123");
            map.put(22, "4321");
            list.add(2.34);
            list.add(5.34);
        }
    }

    private static class ComplexBean {
        private final boolean booleanField = false;
        private final int intField = 1;
        private final Long longField = 2L;
        private final String stringField = "3";
        private final String uncheckedStringField = "3";

        public boolean isBooleanField() {
            return booleanField;
        }

        public int getIntField() {
            return intField;
        }

        public Long getLongField() {
            return longField;
        }

        public String getStringField() {
            return stringField;
        }

        public String getUncheckedStringField() {
            return uncheckedStringField;
        }
    }
}

@@ -88,30 +88,156 @@
 ing.
-reporters.HtmlReporter
+checks.ExecutedCompositeCheck;%0Aimport com.github.alkedr.matchers.reporting.reporters.HtmlReporter;%0Aimport org.apache.commons.lang3.RandomStringUtils
 ;%0Aim
@@ -363,88 +363,9 @@
 til.
-ArrayList;%0Aimport java.util.HashMap;%0Aimport java.util.List;%0Aimport java.util.Map
+*
 ;%0A%0Ai
@@ -771,16 +771,101 @@
 sultOf;%0A
+import static java.lang.Runtime.getRuntime;%0Aimport static org.hamcrest.Matchers.any;%0A
 import s
@@ -1240,16 +1240,16 @@
 n())));%0A
-
         
@@ -1257,16 +1257,825 @@
 %0A    %7D%0A%0A
+    @Test%0A    public void memoryTest() %7B%0A        System.gc();%0A        System.out.println((getRuntime().totalMemory() - getRuntime().freeMemory()) / 1024 + %22 / %22 + getRuntime().totalMemory() / 1024);%0A%0A        Collection%3CString%3E strings = new ArrayList%3C%3E();%0A        for (int i = 0; i %3C 1000000; i++) %7B%0A            strings.add(RandomStringUtils.random(10));%0A        %7D%0A%0A        System.gc();%0A        System.out.println((getRuntime().totalMemory() - getRuntime().freeMemory()) / 1024 + %22 / %22 + getRuntime().totalMemory() / 1024);%0A%0A        ExecutedCompositeCheck report = new ClassifyingMatcher().items(any(String.class), 100000).getReport(strings);%0A%0A        System.gc();%0A        System.out.println((getRuntime().totalMemory() - getRuntime().freeMemory()) / 1024 + %22 / %22 + getRuntime().totalMemory() / 1024);%0A    %7D%0A%0A
 %0A    // 

add memory test