package cz.senslog.analytics.utils.newvalidator;

import java.util.Optional;

class OnChangeNotifyTrigger implements NotifyTrigger {

    private static final int CACHE_LEN = 2;

    private static int nextIndex(int index) {
        return  (index + 1) % CACHE_LEN;
    }

    private static int previousIndex(int index) {
        return (index <= 0 ? CACHE_LEN : index) - 1;
    }

    private static final class ResultCache {
        private final ValidationResult[] resultsArr;
        private int freeIndex;

        private ResultCache(ValidationResult[] resultsArr, int freeIndex) {
            this.resultsArr = resultsArr;
            this.freeIndex = freeIndex;
        }
    }

    private final ResultCache resultCache;

    public OnChangeNotifyTrigger() {
        this.resultCache = new ResultCache(new ValidationResult[CACHE_LEN], 0);
    }

    @Override
    public Optional<NotifyReport> accept(ValidationResult validationResult) {

        resultCache.resultsArr[resultCache.freeIndex] = validationResult;
        resultCache.freeIndex = nextIndex(resultCache.freeIndex);

        int currentDataInd = previousIndex(resultCache.freeIndex);
        ValidationResult currentRes = resultCache.resultsArr[currentDataInd];
        ValidationResult previousRes = resultCache.resultsArr[previousIndex(currentDataInd)];

        if ((previousRes == null || !previousRes.hasViolation()) && currentRes.hasViolation()) {
            // notify about the enter the threshold
            return Optional.of(new NotifyReport(
                currentRes.violatedValue(), currentRes.violatedAttribute(), ("Entry " + currentRes)
            ));
        } else if(!currentRes.hasViolation() && (previousRes != null && previousRes.hasViolation())) {
            // notify about the exit the threshold
            return Optional.of(new NotifyReport(
                    currentRes.violatedValue(), currentRes.violatedAttribute(), ("Exit " + currentRes)
            ));
        }

        // nothing to notify
        return Optional.empty();
    }
}
