package cz.cuni.mff.d3s.spl.example.checksla.checker;

import java.util.HashMap;
import java.util.Map;

import cz.cuni.mff.d3s.spl.core.data.instrumentation.InstrumentingDataSource;
import cz.cuni.mff.d3s.spl.core.data.segment.SlidingSerieDataSource;
import cz.cuni.mff.d3s.spl.core.formula.Formula;
import cz.cuni.mff.d3s.spl.core.formula.Result;
import cz.cuni.mff.d3s.spl.core.formula.SlaFormula;

public class SlaChecker implements Runnable {

	private final static String SHORT_METHOD = "cz.cuni.mff.d3s.spl.example.checksla.app.Main#shortMethod";
	private final static String LONG_METHOD = "cz.cuni.mff.d3s.spl.example.checksla.app.Main#longMethod";
	private final static long SEC_TO_NANOS = 1000 * 1000 * 1000;
	private final static long MILLIS_TO_NANOS = 1000 * 1000;

	private Map<String, Formula> formulas;

	public SlaChecker() {
		formulas = new HashMap<>();
	}

	@Override
	public void run() {
		sleepSec(3);

		init();

		System.err.printf("SlaChecker started!\n");

		while (true) {
			for (Map.Entry<String, Formula> f : formulas.entrySet()) {
				checkFormula(f.getValue(), f.getKey());
			}

			sleepSec(2);
		}
	}

	protected void sleepSec(long sec) {
		try {
			Thread.sleep(sec * 1000);
		} catch (InterruptedException ignored) {
		}
	}

	protected void checkFormula(Formula formula, String name) {
		Result result = formula.evaluate();

		// System.err.printf("Checked contract of %s: %s.\n", name, result);

		if (result == Result.VIOLATES) {
			System.err.printf("Contract of `%s' violated!\n", name);
		}
	}

	private void init() {
		formulas.put("short method", SlaFormula.createSimple(
				SlidingSerieDataSource.create(
						InstrumentingDataSource.create(SHORT_METHOD), 0, 5),
				1 * SEC_TO_NANOS));
		formulas.put("long method", SlaFormula.createSimple(
				SlidingSerieDataSource.create(
						InstrumentingDataSource.create(LONG_METHOD), 0, 5),
				1 * MILLIS_TO_NANOS));
	}

}

@@ -97,16 +97,166 @@
 l.Map;%0A%0A
+import cz.cuni.mff.d3s.spl.agent.Access;%0Aimport cz.cuni.mff.d3s.spl.core.data.SampleBasedDataSource;%0Aimport cz.cuni.mff.d3s.spl.core.data.Statistics;%0A
 import c
@@ -2050,13 +2050,653 @@
 NOS));%0A%09
+%09Access.getMeasurementPoint(InstrumentingDataSource.createId(SHORT_METHOD)).addSink(new ReportWhenMeasured());%0A%09%7D%0A%0A%09private static class ReportWhenMeasured implements SampleBasedDataSource %7B%0A%09%09@Override%0A%09%09public Statistics get() %7B%0A%09%09%09throw new UnsupportedOperationException(%0A%09%09%09%09%09%22Don't know statistics or any mathematics at all, sorry.%22);%0A%09%09%7D%0A%0A%09%09@Override%0A%09%09public void newSample(long sample, long clock) %7B%0A%09%09%09System.err.printf(%22Collected sample %25d at time %25d.%5Cn%22, sample, clock);%0A%09%09%7D%0A%0A%09%09@Override%0A%09%09public void addSubSource(SampleBasedDataSource subSource) %7B%0A%09%09%09throw new UnsupportedOperationException(%22This is not implemented.%22);%0A%09%09%7D%0A%09%09%0A%09
 %7D
-%0A
 %0A%7D%0A

Add simple SampleBasedDataSource to checksla demo