package be.iminds.ilabt.jfed.experimenter_gui.bugreporting;

import be.iminds.ilabt.jfed.bugreport.*;
import be.iminds.ilabt.jfed.call_log_output.HtmlLogOutput;
import be.iminds.ilabt.jfed.call_log_output.SerializableApiCallDetails;
import be.iminds.ilabt.jfed.log.cache.ApiCallDetailsCache;
import be.iminds.ilabt.jfed.log.cache.ApiCallDetailsRef;
import org.rendersnake.HtmlCanvas;

import javax.annotation.Nullable;
import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * User: twalcari
 * Date: 12/11/2015
 * Time: 11:29
 */
public class SerializableStitchingJobReportWriter extends HtmlLogOutput {

    private final StitchingJobReport jobReport;
    private final ApiCallDetailsCache cache;

    public SerializableStitchingJobReportWriter(StitchingJobReport jobReport, ApiCallDetailsCache cache) {
        super("Start Stitching Experiment Report");
        this.jobReport = jobReport;
        this.cache = cache;
    }

    @Override
    public void htmlContent(HtmlCanvas html) throws IOException {
        addClassVisibleToggle(html, "logline-DEBUG", "Debug Log Lines");

        int index = 0;
        for (StitchingJobStateReport reportState : jobReport.getStitchingJobStateReports()) {
            List<SerializableApiCallDetails> callsCopy;
            synchronized (reportState.getTaskExecutions()) {
                callsCopy = reportState.getTaskExecutions().stream()
                        .filter(Objects::nonNull)
                        .flatMap(taskExecution -> taskExecution.getApiCallDetailIds().stream())
                        .map(id -> cache.getApiCallDetails(new ApiCallDetailsRef(id)))
                        .collect(Collectors.toList());
            }
            writeGroup(html,
                    index++,
                    convertExperimentTaskStatus(reportState.getStatus()),
                    reportState.getName() + " calls",
                    "Executed tasks: " + reportState.getTaskExecutions().stream().map(TaskExecutionReport::getName).collect(Collectors.joining(", ")),
                    Duration.between(reportState.getStart(),
                            reportState.getEnd() != null ? reportState.getEnd() : Instant.now()).toMillis(),
                    Date.from(reportState.getStart()),
                    Date.from(reportState.getEnd()),
                    (String) null,
                    callsCopy,
                    null/*todo convert reportState.getLogEntries() here, or make */);
        }
    }
//
//    private static LogEntry convertLogLine(LogLine logLine) {
//        String newlines = logLine.getMessage() == null ? "" : logLine.getMessage().replaceAll("[^\n]*", "");
//        return new LogEntry(
//                LogLineType.valueOf(logLine.getLevel()),
//                logLine.getMessage(),
//                logLine.getTime(),
//                logLine.getException(),
//                newlines.length() > 3/*showAsCode*/);
//    }

    @Nullable
    private static TestResultState convertExperimentTaskStatus(@Nullable String status) {
        if (status == null)
            return null;
        switch (status) {
            case "SUCCESS":
                return TestResultState.SUCCESS;
            case "FAILED":
                return TestResultState.FAILED;
            case "WARNING":
                return TestResultState.WARN;
            default:
                return null;

        }
    }
}
