package org.javarosa.core.model.utils;

import org.javarosa.core.model.trace.EvaluationTrace;
import org.javarosa.core.model.trace.EvaluationTraceReporter;
import org.javarosa.core.model.trace.EvaluationTraceSerializer;

/**
 * Utility functions for instrumentation in the engine
 *
 * Created by ctsims on 7/6/2017.
 */

public class InstrumentationUtils {

    public static void printAndClearTraces(EvaluationTraceReporter reporter, String description) {
        printAndClearTraces(reporter, description, EvaluationTraceSerializer.TraceInfoType.FULL_PROFILE);
    }

    /**
     * Prints out traces (if any exist) from the provided reporter with a description into sysout
     */
    public static void printAndClearTraces(EvaluationTraceReporter reporter, String description,
                                           EvaluationTraceSerializer.TraceInfoType requestedInfo) {
        if (reporter != null) {
            if (reporter.wereTracesReported()) {
                System.out.println(description);
            }

            EvaluationTraceSerializer serializer = new EvaluationTraceSerializer();

            for (EvaluationTrace trace : reporter.getCollectedTraces()) {
                System.out.println(trace.getExpression() + ": " + trace.getValue());
                System.out.print(serializer.serializeEvaluationTrace(trace, requestedInfo, reporter.reportAsFlat()));
            }

            reporter.reset();
        }
    }

    /**
     * Prints out traces (if any exist) from the provided reporter with a description into sysout
     */
    public static String collectAndClearTraces(EvaluationTraceReporter reporter, String description,
                                               EvaluationTraceSerializer.TraceInfoType requestedInfo) {
        String returnValue = "";
        if (reporter != null) {
            if (reporter.wereTracesReported()) {
                returnValue += description + "\n";
            }

            EvaluationTraceSerializer serializer = new EvaluationTraceSerializer();

            for (EvaluationTrace trace : reporter.getCollectedTraces()) {
                returnValue += trace.getExpression() + ": " + trace.getValue()  + "\n";
                returnValue += serializer.serializeEvaluationTrace(trace, requestedInfo, reporter.reportAsFlat());
            }

            reporter.reset();
        }
        return returnValue;
    }

    public static void printExpressionsThatUsedCaching(EvaluationTraceReporter reporter, String description) {
        if (reporter != null) {
            if (reporter.wereTracesReported()) {
                System.out.println(description);
            }

            for (EvaluationTrace trace : reporter.getCollectedTraces()) {
                if (trace.evaluationUsedExpressionCache()) {
                    System.out.println(trace.getExpression() + ": " + trace.getValue());
                    System.out.println("    " + trace.getCacheReport());
                }
            }
        }
    }

}

@@ -214,16 +214,100 @@
 lizer;%0A%0A
+import java.util.ArrayList;%0Aimport java.util.List;%0Aimport java.util.stream.Stream;%0A%0A
 /**%0A * U
@@ -3081,10 +3081,1256 @@
 %0A    %7D%0A%0A
+    public static void printCachedAndNotCachedExpressions(EvaluationTraceReporter reporter, String description) %7B%0A        if (reporter != null) %7B%0A            if (reporter.wereTracesReported()) %7B%0A                System.out.println(description);%0A            %7D%0A%0A            List%3CEvaluationTrace%3E withCaching = new ArrayList%3C%3E();%0A            List%3CEvaluationTrace%3E withoutCaching = new ArrayList%3C%3E();%0A            for (EvaluationTrace trace : reporter.getCollectedTraces()) %7B%0A                if (trace.evaluationUsedExpressionCache()) %7B%0A                    withCaching.add(trace);%0A                %7D else %7B%0A                    withoutCaching.add(trace);%0A                %7D%0A            %7D%0A%0A            System.out.println(%22EXPRESSIONS NEVER CACHED: %22 + withoutCaching.size());%0A            for (EvaluationTrace trace : withoutCaching) %7B%0A                System.out.println(trace.getExpression() + %22: %22 + trace.getValue());%0A            %7D%0A%0A            System.out.println(%22EXPRESSIONS CACHED: %22 + withoutCaching.size());%0A            for (EvaluationTrace trace : withCaching) %7B%0A                System.out.println(trace.getExpression() + %22: %22 + trace.getValue());%0A                System.out.println(%22    %22 + trace.getCacheReport());%0A            %7D%0A        %7D%0A    %7D%0A%0A
 %7D%0A

add util method for printing cached and not-cached expressions