package cz.senslog.analytics.utils.validator;

import cz.senslog.analytics.domain.*;
import cz.senslog.analytics.utils.validator.domain.ThresholdValidationResult;
import cz.senslog.analytics.utils.validator.domain.ValidationReport;
import cz.senslog.analytics.utils.validator.domain.ValidationResult;

import java.util.*;

/**
 * The class InstantNotifyTrigger is unique for each datasource, i.e., unit/sensor = one NotifyTrigger
 */
public class InstantNotifyTrigger implements NotifyTrigger {

    private final Map<Long, ThresholdValidationResult> currentResultMap;
    private Set<Long> tempAttrsToNotify;

    public InstantNotifyTrigger() {
        this.currentResultMap = new HashMap<>();
    }

    @Override
    public void accept(Threshold threshold, ValidationResult... validationResults) {
        currentResultMap.put(threshold.id(), new ThresholdValidationResult(threshold, validationResults));
    }

    @Override
    public Mode mode() {
        return Mode.INSTANT;
    }

    @Override
    public boolean shouldNotify() {
        boolean notify = false;
        tempAttrsToNotify = new HashSet<>();
        for (Map.Entry<Long, ThresholdValidationResult> thresholdResultEntry : currentResultMap.entrySet()) {
            if (thresholdResultEntry.getValue().isViolated()) {
                notify = true;
                tempAttrsToNotify.add(thresholdResultEntry.getKey());
            }
        }
        return notify;
    }

    @Override
    public ValidationReport resultsToNotify() {

        if (tempAttrsToNotify.isEmpty()) {
            return ValidationReport.empty();
        }

        StringBuilder alertMessageBuilder = new StringBuilder();
        List<ValidationResult> attributeValidationResults = new ArrayList<>();

        for (Long thresholdId : tempAttrsToNotify) {
            ThresholdValidationResult thResult = currentResultMap.get(thresholdId);
            attributeValidationResults.addAll(Arrays.asList(thResult.validationResults()));

            if (thResult.threshold().enableAlert()) {
                String alertMessage = thResult.threshold().customAlertMessage();
                if (alertMessage != null) {
                    alertMessageBuilder.append(alertMessage).append("\n");
                }
            }
        }

        tempAttrsToNotify = null;

        return new ValidationReport(
                alertMessageBuilder.toString(),
                attributeValidationResults.toArray(new ValidationResult[0])
        );
    }
}
