package com.grayben.riskExtractor.helpers;

import com.grayben.riskExtractor.htmlScorer.HtmlScorer;
import com.grayben.riskExtractor.htmlScorer.ScoredText;
import com.grayben.riskExtractor.htmlScorer.ScoringAndFlatteningNodeVisitor;
import com.grayben.riskExtractor.htmlScorer.TreeHtmlScorer;
import com.grayben.riskExtractor.htmlScorer.partScorers.Scorer;
import com.grayben.tools.testOracle.SystemUnderTest;
import com.grayben.tools.testOracle.oracle.passive.PassiveOracle;
import com.grayben.tools.testOracle.testContainer.TestContainer;
import org.jsoup.nodes.Element;

import java.io.InputStream;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * Created by Ben Gray on 19/02/2016.
 */
public class TreeHtmlScorerReverserTestContainerSupplier implements Supplier<TestContainer<ScoredText, ScoredText>> {

    private final Supplier<Set<Scorer<Element>>> elementScorersSupplier;

    public TreeHtmlScorerReverserTestContainerSupplier(Supplier<Set<Scorer<Element>>> elementScorersSupplier) {
        this.elementScorersSupplier = elementScorersSupplier;
    }

    @Override
    public TestContainer<ScoredText, ScoredText> get() {
        return new TestContainer.Builder<ScoredText, ScoredText>()
                .begin()
                .systemUnderTest(systemUnderTest())
                .oracle(passiveOracle())
                .build();
    }

    private PassiveOracle<ScoredText, ScoredText> passiveOracle(){
        return (input, actualOutput) -> input.equals(actualOutput);
    }

    /**
     *
     * @return an InputStream for which a correct implementation of TreeHtmlScorer will produce the specified ScoredText
     */
    private Function<ScoredText, InputStream> reverse(){
        return scoredText -> ScoredTextReverseEngineerer.inputStreamFromElementScorers(scoredText, elementScorersSupplier.get());
    }

    private Function<InputStream, ScoredText> forward(){
        return inputStream -> {
            ScoringAndFlatteningNodeVisitor nv = new ScoringAndFlatteningNodeVisitor(elementScorersSupplier.get());
            HtmlScorer htmlScorer = new TreeHtmlScorer(nv);
            return htmlScorer.scoreHtml(inputStream, "unicode", "");
        };

    }

    private SystemUnderTest<ScoredText, ScoredText> systemUnderTest() {
        return scoredText -> reverse().andThen(forward()).apply(scoredText);
    }


}

@@ -567,16 +567,44 @@
 ement;%0A%0A
+import java.io.IOException;%0A
 import j
@@ -2188,63 +2188,253 @@
     
-return htmlScorer.scoreHtml(inputStream, %22unicode%22, %22%22)
+ScoredText scoredText = null;%0A            try %7B%0A                scoredText = htmlScorer.scoreHtml(inputStream, %22unicode%22, %22%22);%0A            %7D catch (IOException e) %7B%0A                e.printStackTrace();%0A            %7D%0A            return scoredText
 ;%0A  

Use try-catch block for htmlScorer.scoreHtml()