/*
 * Copyright (c) 2012 Mateusz Parzonka, Eric Bodden
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * Mateusz Parzonka - initial API and implementation
 */
package prm4j.indexing.realtime;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.junit.Test;

import prm4j.AbstractTest;
import prm4j.api.fsm.FSM;
import prm4j.api.fsm.FSMSpec;
import prm4j.indexing.BaseMonitor;
import prm4j.indexing.staticdata.StaticDataConverter;
import prm4j.spec.FiniteParametricProperty;
import prm4j.spec.FiniteSpec;

public class DefaultParametricMonitorTest extends AbstractTest {

    StaticDataConverter converter;
    AwareDefaultBindingStore bindingStore;
    AwareDefaultNodeStore nodeStore;
    AwareBaseMonitor prototypeMonitor;
    DefaultParametricMonitor pm;

    AwareBaseMonitor monitor; // working variable

    public void createDefaultParametricMonitorWithAwareComponents(FiniteSpec finiteSpec) {
	converter = new StaticDataConverter(new FiniteParametricProperty(finiteSpec));
	bindingStore = new AwareDefaultBindingStore(finiteSpec.getFullParameterSet(), 1);
	nodeStore = new AwareDefaultNodeStore(converter.getMetaTree());
	prototypeMonitor = new AwareBaseMonitor();
	pm = new DefaultParametricMonitor(bindingStore, nodeStore, prototypeMonitor, converter.getEventContext());
    }

    @Test
    public void newEvents_monitorUpdatesTimestampBoundObjects() throws Exception {
	FSM_threeSameStrings fsm = new FSM_threeSameStrings();
	FiniteSpec finiteSpec = new FSMSpec(fsm.fsm);

	createDefaultParametricMonitorWithAwareComponents(finiteSpec);

	String a = "a";
	String b = "b";

	// exercise
	pm.processEvent(fsm.createString.createEvent(a));
	pm.processEvent(fsm.createString.createEvent(b));

	// verify
	monitor = popNextUpdatedMonitor();
	assertCreationTime(0L, monitor);
	assertBoundObjects(monitor, a);
	monitor = popNextUpdatedMonitor();
	assertCreationTime(1L, monitor);
	assertBoundObjects(monitor, b);
	assertNoMoreUpdatedMonitors();

    }

    private void assertCreationTime(long timeStamp, BaseMonitor monitor) {
	assertEquals(timeStamp, monitor.getCreationTime());
    }

    public AwareBaseMonitor popNextUpdatedMonitor() {
	return prototypeMonitor.getUpdatedMonitors().pop();
    }

    private void assertBoundObjects(AwareBaseMonitor monitor, Object... boundObjects) {
	LowLevelBinding[] bindings = monitor.getLowLevelBindings();
	Object[] monitorBoundObjects = new Object[bindings.length];
	for (int i = 0; i < bindings.length; i++) {
	    monitorBoundObjects[i] = bindings[i].get();
	}
	assertArrayEquals(boundObjects, monitorBoundObjects);
    }

    public void assertNoMoreUpdatedMonitors() {
	assertTrue("There were more updated monitors: " + prototypeMonitor.getUpdatedMonitors(), prototypeMonitor
		.getUpdatedMonitors().isEmpty());
    }
}

@@ -547,136 +547,70 @@
 ue;%0A
-%0A
 import 
-java.util.Collection;%0Aimport java.util.HashMap;%0Aimport java.util.Iterator
+static org.junit.Assert.fail
 ;%0A
+%0A
 import 
-java.util.List;%0Aimport java.util.Map;%0A
+org.junit.Before;
 %0Aimp
@@ -661,34 +661,8 @@
 st;%0A
-import prm4j.api.fsm.FSM;%0A
 impo
@@ -1156,16 +1156,125 @@
 riable%0A%0A
+    FSM_threeSameStrings fsm;%0A    final String a = %22a%22;%0A    final String b = %22a%22;%0A    final String c = %22a%22;%0A%0A
     publ
@@ -1748,20 +1748,22 @@
 %7D%0A%0A    @
-Test
+Before
 %0A    pub
@@ -1775,97 +1775,18 @@
 oid 
-newEvents_monitorUpdatesTimestampBoundObjects() throws Exception %7B%0A%09FSM_threeSameStrings 
+init() %7B%0A%09
 fsm 
@@ -1862,17 +1862,16 @@
 m.fsm);%0A
-%0A
 %09createD
@@ -1925,16 +1925,116 @@
 teSpec);
+%0A    %7D%0A%0A    @Test%0A    public void newEvents_monitorUpdatesTimestampBoundObjects() throws Exception %7B
 %0A%0A%09Strin
@@ -2427,17 +2427,16 @@
 tors();%0A
-%0A
     %7D%0A%0A 
@@ -2623,16 +2623,121 @@
 tor() %7B%0A
+%09if (prototypeMonitor.getUpdatedMonitors().isEmpty())%0A%09    fail(%22There were no more updated monitors!%22);%0A
 %09return 

Refactor DefaultParametricMonitorTest