%general includes
:-eval(consult('ContractLog/math.prova')).
:-eval(consult('ContractLog/list.prova')).
:-eval(consult('ContractLog/list_math.prova')).
:-eval(consult('ContractLog/datetime.prova')).
:-eval(consult('ContractLog/timeinterval.prova')).
:-eval(consult('ContractLog/ecaruntime.prova')).
:-eval(consult('ContractLog/utils.prova')).
:-eval(consult('ContractLog/ec.prova')).
:-eval(consult('ContractLog/update.prova')).


%includes of the contract
:-eval(consult('examples/sla_examples/example2/facts.prova')).
:-eval(consult('examples/sla_examples/example2/storeDB.prova')).


:- eval(startContract()).
startContract() :-
	hideTimer(),
	startECARuntime("examples/sla_examples/example2/qsc.prova").

%=========== ECA die Verfügbarkeit testet ============%
eca(timeInterval(DT), getServers(Srv), not(isAvailable(DT, Srv)), notAvailable(DT, Srv), _,_).

timeInterval(DT) :-
	sysTime(DT),
	sec(S),
	interval(timespan(0,0,0,S), DT),
	checkPeriod(DT),
	holdsAt(normalTime, DT),
	!.
	
	
checkPeriod(DT) :-
	DT=[N,Y,M,D,H,Min,Sec],
	H=6,
	Min=0,
	Sec<20,
	assert(happens(normal, DT)),
	!.

checkPeriod(DT) :-
	DT=[N,Y,M,D,H,Min,Sec],
	H=0,
	Min=0,
	Sec<20,
	assert(happens(maintain, DT)),
	!.

checkPeriod(DT) :-
	1>0.
	
getServers(Srv) :-
	server(Srv),
	println([Srv]).


%==== isAvailable ====

isAvailable(DT, Srv) :-
	X=rbsla.utils.contractQsc.Qsc(),
	X.testWebserver(Srv),
	!,
	storeAvailability(DT, Srv, 1),
	endOfMonthCalc(DT, Srv),
	aval(DT, Srv),
	retractall(actEskLvl(_, Srv)).

isAvailable(DT, Srv) :-
	storeAvailability(DT, Srv, 0),
	endOfMonthCalc(DT, Srv),
	naval(DT, Srv),
	!,
	fail().
	
aval(DT, Srv) :-
	holdsAt(Srv, DT),
	!.

aval(DT, Srv) :-
	assert(happens(serverGeht(Srv), DT)),
	storeHappens(serverGeht(Srv), DT).

naval(DT, Srv) :-
	holdsAt(Srv, DT),
	assert(happens(serverAusfall(Srv), DT)),
	storeHappens(serverAusfall(Srv), DT),
	!.
	
naval(DT, Srv) :-
	1>0,
	!.
	
notAvailable(DT, Srv) :-
	increaseEskLevel(DT, Srv).
	


%==== increaseEskLevel ====

increaseEskLevel(DT, Srv) :-
	actEskLvl(X, Srv),
	!,
	repairTime(T, Srv),
	sec(S),
	java_sub(T, S, NR),			
	retract(repairTime(T, Srv)),
	assert(repairTime(NR, Srv)),
	println(["---" , NR]),
	NR<S,	
	println(["eskaltionsLevel erhoeht"]),
	java_add(X, 1, Y),
	retract(actEskLvl(X, Srv)),
	assert(actEskLvl(Y, Srv)), 
	eskLvl(Y, T1, Mail),
	retractall(repairTime(_, Srv)),
	assert(repairTime(T1, Srv)).


increaseEskLevel(DT, Srv) :-
	!,
	assert(actEskLvl(1, Srv)),
	%countdown einleiten	
	eskLvl(1, T, Mail),
	assert(repairTime(T, Srv)).
	
	
firstOfMonth(DT) :-
	DT = [N, Y, M, D, H, Min, Sec], 
	D = 1,
	H = 0.
	
	
	
endOfMonthCalc(DT, Srv) :-
	firstOfMonth(DT),
	DT = [N, Y, M, D, H, Min, Sec], 
	minavalability(MinAval),
	Ob=rbsla.utils.contractQsc.Qsc(),
	Diff=Ob.endOfMonthCalculation(Y, M, Srv, MinAval),
	Diff<0,
	!,
	strafen(Srv, Diff).
	
endOfMonthCalc(DT, Srv) :-
	1>0.
	
	
%festgelegte Strafen
strafen(Srv, Diff) :-
	println([Diff]),
	Diff > -3,
	!,
	println(["leichte Strafe"]).
	
strafen(Srv, Diff) :-
	Diff > -5,
	!,
	println(["mittlere Strafe"]).
	
strafen(Srv, Diff) :-
	!,
	println(["Vertragskuendigung"]).