/*
* Copyright (c) 2020 Kentyou.
 * 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:
*    Kentyou - initial API and implementation
 */
package org.eclipse.sensinact.gateway.core.test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.lang.reflect.Method;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import org.eclipse.sensinact.gateway.common.constraint.Changed;
import org.eclipse.sensinact.gateway.common.constraint.Constraint;
import org.eclipse.sensinact.gateway.common.constraint.MaxLength;
import org.eclipse.sensinact.gateway.common.constraint.MinLength;
import org.eclipse.sensinact.gateway.common.execution.ErrorHandler;
import org.eclipse.sensinact.gateway.common.execution.Executable;
import org.eclipse.sensinact.gateway.common.primitive.InvalidValueException;
import org.eclipse.sensinact.gateway.common.primitive.Modifiable;
import org.eclipse.sensinact.gateway.common.props.TypedProperties;
import org.eclipse.sensinact.gateway.core.ActionResource;
import org.eclipse.sensinact.gateway.core.Attribute;
import org.eclipse.sensinact.gateway.core.DataResource;
import org.eclipse.sensinact.gateway.core.FilteringCollection;
import org.eclipse.sensinact.gateway.core.FilteringDefinition;
import org.eclipse.sensinact.gateway.core.InvalidServiceProviderException;
import org.eclipse.sensinact.gateway.core.LocationResource;
import org.eclipse.sensinact.gateway.core.Metadata;
import org.eclipse.sensinact.gateway.core.ModelInstance;
import org.eclipse.sensinact.gateway.core.PropertyResource;
import org.eclipse.sensinact.gateway.core.Resource;
import org.eclipse.sensinact.gateway.core.ResourceImpl;
import org.eclipse.sensinact.gateway.core.Service;
import org.eclipse.sensinact.gateway.core.ServiceImpl;
import org.eclipse.sensinact.gateway.core.ServiceProvider;
import org.eclipse.sensinact.gateway.core.Session;
import org.eclipse.sensinact.gateway.core.StateVariableResource;
import org.eclipse.sensinact.gateway.core.message.AbstractMidAgentCallback;
import org.eclipse.sensinact.gateway.core.message.Recipient;
import org.eclipse.sensinact.gateway.core.message.SnaErrorMessageImpl;
import org.eclipse.sensinact.gateway.core.message.SnaFilter;
import org.eclipse.sensinact.gateway.core.message.SnaLifecycleMessageImpl;
import org.eclipse.sensinact.gateway.core.message.SnaMessage;
import org.eclipse.sensinact.gateway.core.message.SnaResponseMessage;
import org.eclipse.sensinact.gateway.core.message.SnaUpdateMessageImpl;
import org.eclipse.sensinact.gateway.core.method.AccessMethod;
import org.eclipse.sensinact.gateway.core.method.AccessMethodExecutor;
import org.eclipse.sensinact.gateway.core.method.AccessMethodResponse;
import org.eclipse.sensinact.gateway.core.method.AccessMethodResponseBuilder;
import org.eclipse.sensinact.gateway.core.method.GetResponse;
import org.eclipse.sensinact.gateway.core.method.LinkedActMethod;
import org.eclipse.sensinact.gateway.core.method.Parameter;
import org.eclipse.sensinact.gateway.core.method.SetResponse;
import org.eclipse.sensinact.gateway.core.method.Shortcut;
import org.eclipse.sensinact.gateway.core.method.Signature;
import org.eclipse.sensinact.gateway.core.method.SubscribeResponse;
import org.eclipse.sensinact.gateway.core.method.trigger.Constant;
import org.eclipse.sensinact.gateway.core.security.AccessProfileOption;
import org.eclipse.sensinact.gateway.core.security.AccessTree;
import org.eclipse.sensinact.gateway.core.security.AccessTreeImpl;
import org.eclipse.sensinact.gateway.core.security.SecuredAccessException;
import org.eclipse.sensinact.gateway.datastore.api.DataStoreException;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.InvalidSyntaxException;
import org.skyscreamer.jsonassert.JSONAssert;


/**
 * Test ResourceFactory
 */
@SuppressWarnings({ "rawtypes" })
public class TestResourceBuilder<R extends ModelInstance> {
	protected TestContext testContext;
	protected Dictionary<String, Object> props;
	protected AccessTree tree;

	private final BundleContext context = Mockito.mock(BundleContext.class);
	private final Bundle bundle = Mockito.mock(Bundle.class);

	@Before
	public void init() throws InvalidServiceProviderException, InvalidSyntaxException, SecuredAccessException,
			DataStoreException, BundleException {
		try {
		this.testContext = new TestContext();
		this.tree = new AccessTreeImpl(testContext.getMediator()).withAccessProfile(AccessProfileOption.ALL_ANONYMOUS);
		}catch(Exception e) {
			e.printStackTrace();
		}
	}

	@After
	public void tearDown() {
		this.testContext.stop();
	}

	@Test
	public void testSessionMethods() throws Exception {
		ServiceImpl service = this.testContext.getModelInstance().getRootElement().addService("testService");

		ResourceImpl r1impl = service.addDataResource(PropertyResource.class, "TestProperty", String.class, "hello");

		Session session = this.testContext.getSensiNact().getAnonymousSession();

		PropertyResource r1 = r1impl.<PropertyResource>getProxy(this.tree);

		// test shortcut
		Assert.assertEquals("TestProperty", r1.getName());
		Assert.assertEquals(Resource.Type.PROPERTY, r1.getType());

		String get1 = session.get("serviceProvider", "testService", "TestProperty", DataResource.VALUE).getJSON();

		String get2 = r1.get().getJSON();

		JSONAssert.assertEquals(get1, get2, false);

		final JSONObject changed = new JSONObject(
				new Changed(Thread.currentThread().getContextClassLoader(), true).getJSON());

		SubscribeResponse res = session.subscribe("serviceProvider", "testService", "TestProperty", new Recipient() {
			@Override
			public void callback(String callbackId, SnaMessage[] messages) throws Exception {
				boolean hasChanged = ((TypedProperties<?>) messages[0]).<Boolean>get("hasChanged");
				if (!hasChanged){
					TestResourceBuilder.this.testContext.extraCallbackInc();
				}
			}

			@Override
			public String getJSON() {
				return null;
			}
		}, new JSONArray() {
			{
				this.put(changed);
			}
		});
		session.set("serviceProvider", "testService", "TestProperty", DataResource.VALUE, "hello");

		Thread.sleep(500);

		Assert.assertEquals(1, this.testContext.getExtraCallbackCount());

		ResourceImpl r2impl = service.addDataResource(PropertyResource.class, "TestProperty2", String.class, null);

		ResourceImpl r3impl = service.addLinkedResource("LinkedProperty", r1impl);

		// test linked resource
		JSONAssert.assertEquals(session.get("serviceProvider", "testService", "TestProperty", null).getResponse(),
				session.get("serviceProvider", "testService", "LinkedProperty", DataResource.VALUE).getResponse(),
				false);

		session.set("serviceProvider", "testService", "LinkedProperty", DataResource.VALUE, "testLink");

		JSONAssert.assertEquals(
				session.get("serviceProvider", "testService", "TestProperty", DataResource.VALUE).getResponse(),
				session.get("serviceProvider", "testService", "LinkedProperty", null).getResponse(), false);

		service.addLinkedResource(LocationResource.LOCATION, this.testContext.getModelInstance().getRootElement()
				.getAdminService().getResource(LocationResource.LOCATION));

		ResourceImpl r4impl = service.getResource("location");

		r4impl.registerExecutor(AccessMethod.Type.valueOf(AccessMethod.GET), new Class<?>[0], new String[0],
				new AccessMethodExecutor() {
					@Override
					public Void execute(AccessMethodResponseBuilder result) throws Exception {
						JSONObject jsonObject = (JSONObject) result.getAccessMethodObjectResult();
						jsonObject.put("value",new StringBuilder().append(jsonObject.get("value")).append("_suffix").toString());
						result.setAccessMethodObjectResult(jsonObject);
						return null;
					}
				}, AccessMethodExecutor.ExecutionPolicy.AFTER);

		String attributeValue = (String) r4impl.getAttribute("value").getValue();

		Thread.sleep(250);

		StringBuilder buffer = new StringBuilder();
		buffer.append(attributeValue);
		buffer.append("_suffix");

		JSONObject message = new JSONObject(
				session.get("serviceProvider", "testService", "location", DataResource.VALUE).getJSON());

		assertEquals(buffer.toString(), message.getJSONObject("response").getString(DataResource.VALUE));

		// test subscription
		String subId = session.subscribe("serviceProvider", "testService", "TestProperty2", new Recipient() {
			@Override
			public void callback(String callbackId, SnaMessage[] messages) throws Exception {
				TestResourceBuilder.this.testContext.callbackInc();
			}

			@Override
			public String getJSON() {
				return null;
			}
		}, null).getResponse().getString("subscriptionId");

		session.subscribe("serviceProvider", "testService", "LinkedProperty", new Recipient() {
			@Override
			public void callback(String callbackId, SnaMessage[] messages) throws Exception {
				TestResourceBuilder.this.testContext.linkCallbackInc();
			}

			@Override
			public String getJSON() {
				return null;
			}
		}, null);

		JSONObject set1 = session.set("serviceProvider", "testService", "TestProperty2", null, "property3").getResponse();
		Thread.sleep(250);
		JSONObject set2 = session.set("serviceProvider", "testService", "TestProperty2", DataResource.VALUE, "property3").getResponse();
		Assert.assertEquals(set1.get(DataResource.VALUE), set2.get(DataResource.VALUE));
		JSONObject set3 = session.set("serviceProvider", "testService", "TestProperty", DataResource.VALUE, "TEST LINKED SUBSCRIPTION").getResponse();

		Thread.sleep(250);

		long time1 = (Long) set1.get(Metadata.TIMESTAMP);
		long time2 = (Long) set2.get(Metadata.TIMESTAMP);

		Thread.sleep(500);
		Assert.assertTrue(time1 != time2);
		assertEquals(1, this.testContext.getCallbackCount());

		session.set("serviceProvider", "testService", "TestProperty2", null, "property5");
		Thread.sleep(500);
		assertEquals(2, this.testContext.getCallbackCount());

		String filter = "/serviceProvider/testService/TestProperty2/value";
		org.junit.Assert.assertEquals(1,
				((MyModelInstance) this.testContext.getModelInstance()).getHandler().count(filter));

		session.unsubscribe("serviceProvider", "testService", "TestProperty2", subId);

		org.junit.Assert.assertEquals(0,
				((MyModelInstance) this.testContext.getModelInstance()).getHandler().count(filter));

		Service proxy = service.<Service>getProxy(this.tree);
		SetResponse error = proxy.set("location", DataResource.VALUE, "unknown");
		assertTrue(error.getStatusCode() == 403);
		assertEquals(1, this.testContext.getLinkCallbackCount());
	}

	@Test
	public void testResourceModel() throws Exception {
		ServiceImpl service = this.testContext.getModelInstance().getRootElement().addService("testService");

		ResourceImpl r1impl = service.addDataResource(PropertyResource.class, "TestProperty", String.class, "hello");

		PropertyResource r1 = r1impl.<PropertyResource>getProxy(this.tree);

		// test shortcut
		Assert.assertEquals("TestProperty", r1.getName());
		Assert.assertEquals(Resource.Type.PROPERTY, r1.getType());

		String get1 = r1.get(DataResource.VALUE).getJSON();		
		String get2 = r1.get().getJSON();
		
		JSONAssert.assertEquals(get1, get2, false);
		SubscribeResponse res = r1.subscribe(new Recipient() {
			@Override
			public void callback(String callbackId, SnaMessage[] messages) throws Exception {
				boolean hasChanged = ((TypedProperties<?>) messages[0]).<Boolean>get("hasChanged");
				if (!hasChanged)
					TestResourceBuilder.this.testContext.extraCallbackInc();
			}
			
			@Override
			public String getJSON() {
				return null;
			}
		}, new HashSet<Constraint>() {{
				this.add(new Changed(Thread.currentThread().getContextClassLoader(), true));
		}});

		r1.set("hello");
		Thread.sleep(500);

		Assert.assertTrue("the message should have been processed even if the value has not changed",
				1 == this.testContext.getExtraCallbackCount());

		ResourceImpl r2impl = service.addDataResource(PropertyResource.class, "TestProperty2", String.class, null);

		PropertyResource r2 = r2impl.<PropertyResource>getProxy(this.tree);
		ResourceImpl r3impl = service.addLinkedResource("LinkedProperty", r1impl);
		PropertyResource r3 = r3impl.<PropertyResource>getProxy(this.tree);

		ResourceImpl r4impl = service.addLinkedResource(LocationResource.LOCATION, this.testContext.getModelInstance().getRootElement()
				.getAdminService().getResource(LocationResource.LOCATION));

		// test linked resource
		JSONAssert.assertEquals(((GetResponse) r1.get()).getResponse(), ((GetResponse) r3.get()).getResponse(), false);

		r1.set("testLink");

		JSONAssert.assertEquals(((GetResponse) r1.get()).getResponse(), ((GetResponse) r3.get()).getResponse(), false);

		r4impl.registerExecutor(AccessMethod.Type.valueOf(AccessMethod.GET), new Class<?>[0], new String[0],
			new AccessMethodExecutor() {
				@Override
				public Void execute(AccessMethodResponseBuilder result) throws Exception {
					JSONObject jsonObject = (JSONObject) result.getAccessMethodObjectResult();
					jsonObject.put("value", new StringBuilder().append(jsonObject.get("value")).append("_suffix").toString());
					result.setAccessMethodObjectResult(jsonObject);
					return null;
				}
			}, AccessMethodExecutor.ExecutionPolicy.AFTER);

		String attributeValue = (String) r4impl.getAttribute("value").getValue();
		LocationResource r4 = r4impl.<LocationResource>getProxy(this.tree);

		Thread.sleep(250);

		StringBuilder buffer = new StringBuilder();
		buffer.append(attributeValue);
		buffer.append("_suffix");

		SnaMessage message = r4.get(DataResource.VALUE);

		JSONObject object = ((GetResponse) message).getResponse();
		assertEquals(buffer.toString(), object.getString(DataResource.VALUE));

		// test subscription
		String subId = ((SubscribeResponse) r2.subscribe(new Recipient() {
			@Override
			public void callback(String callbackId, SnaMessage[] messages) throws Exception {
				TestResourceBuilder.this.testContext.callbackInc();
			}

			@Override
			public String getJSON() {
				return null;
			}
		})).getSubscriptionId();

		r3.subscribe(new Recipient() {
			@Override
			public void callback(String callbackId, SnaMessage[] messages) throws Exception {
				TestResourceBuilder.this.testContext.linkCallbackInc();
			}

			@Override
			public String getJSON() {
				return null;
			}
		});
		JSONObject set1 = r2.set("property3").getResponse();
		Thread.sleep(250);

		JSONObject set2 = r2.set("value", "property3").getResponse();

		Assert.assertEquals(set1.get(DataResource.VALUE), set2.get(DataResource.VALUE));

		JSONObject set3 = r1.set("value", "TEST LINKED SUBSCRIPTION").getResponse();
		Thread.sleep(250);

		long time1 = (Long) set1.get(Metadata.TIMESTAMP);
		long time2 = (Long) set2.get(Metadata.TIMESTAMP);

		Thread.sleep(500);
		Assert.assertTrue(time1 != time2);
		assertEquals(1, this.testContext.getCallbackCount());

		r2.set("value", "property5").getJSON();
		Thread.sleep(500);
		assertEquals(2, this.testContext.getCallbackCount());

		String filter = "/serviceProvider/testService/TestProperty2/value";
		org.junit.Assert.assertEquals(1,
				((MyModelInstance) this.testContext.getModelInstance()).getHandler().count(filter));
		r2.unsubscribe(subId);
		org.junit.Assert.assertEquals(0,
				((MyModelInstance) this.testContext.getModelInstance()).getHandler().count(filter));

		Service proxy = service.<Service>getProxy(this.tree);
		SetResponse error = proxy.set("location", DataResource.VALUE, (Object)"unknown");
		assertTrue(error.getStatusCode() == 403);
		assertEquals(1, this.testContext.getLinkCallbackCount());
	}

	@Test
	public void testAgent() throws Exception {
		
		ServiceImpl service1 = this.testContext.getModelInstance().getRootElement().addService("testService");
		ResourceImpl r1impl = service1.addDataResource(PropertyResource.class, "TestProperty", String.class, "hello");
		ServiceImpl service2 = this.testContext.getModelInstance().getRootElement().addService("tostService");
		ResourceImpl r2impl = service2.addDataResource(PropertyResource.class, "TestProperty", String.class, "hello");
		
		// wait for the previously generated events to be consumed
		Thread.sleep(1000);
		SnaFilter filter = new SnaFilter(this.testContext.getMediator(), "/serviceProvider/(test).*", true, false);

		filter.addHandledType(SnaMessage.Type.UPDATE);
		String agentId = this.testContext.getSensiNact().registerAgent(this.testContext.getMediator(), new AbstractMidAgentCallback() {
			@Override
			public void doHandle(SnaUpdateMessageImpl message) {
				TestResourceBuilder.this.testContext.agentCallbackInc();
				// System.out.println("TestResourceBuilder.this.agentCallbackCount++");
			}
		}, filter);
		//System.out.println("AGENT ID = " + agentId);
		PropertyResource r1 = r1impl.<PropertyResource>getProxy(this.tree);
		PropertyResource r2 = r2impl.<PropertyResource>getProxy(this.tree);

		assertEquals(0, TestResourceBuilder.this.testContext.getAgentCallbackCount());
		System.out.println(r2.set("goodbye").getJSON());

		Thread.sleep(250);
		assertEquals(0, TestResourceBuilder.this.testContext.getAgentCallbackCount());

		System.out.println(r1.set("goodbye").getJSON());

		Thread.sleep(250);
		assertEquals(1, TestResourceBuilder.this.testContext.getAgentCallbackCount());

		Mockito.when(this.testContext.getMediator().getContext().getProperty(Mockito.anyString()))
				.thenAnswer(new Answer<Object>() {
					@Override
					public String answer(InvocationOnMock invocation) throws Throwable {
						String parameter = (String) invocation.getArguments()[0];
						if ("org.eclipse.sensinact.gateway.filter.suffix".equals(parameter)) {
							return "test";
						}
						if ("org.eclipse.sensinact.gateway.filter.types.test".equals(parameter)) {
							return "LIFECYCLE";
						}
						if ("org.eclipse.sensinact.gateway.filter.sender.test".equals(parameter)) {
							return "/(serviceProvider)/(test).*";
						}
						if ("org.eclipse.sensinact.gateway.filter.pattern.test".equals(parameter)) {
							return "true";
						}
						if ("org.eclipse.sensinact.gateway.filter.complement.test".equals(parameter)) {
							return "true";
						}
						if ("org.eclipse.sensinact.gateway.filter.conditions.test".equals(parameter)) {
							return null;
						}
						return null;
					}
				});
		TestResourceBuilder.this.testContext.agentCallbackCountReset();
		this.testContext.getSensiNact().registerAgent(this.testContext.getMediator(), new AbstractMidAgentCallback() {
			@Override
			public void doHandle(SnaLifecycleMessageImpl message) {

				TestResourceBuilder.this.testContext.agentCallbackInc();
			}

			@Override
			public void doHandle(SnaErrorMessageImpl message) {
			}

			@Override
			public void doHandle(SnaResponseMessage message) {
			}

			@Override
			public void doHandle(SnaUpdateMessageImpl message) {
			}

			@Override
			public void stop() {
			}
		}, null);

		this.testContext.getModelInstance().getRootElement().stop();
		Thread.sleep(500);

		// {"notification":{"lifecycle":"RESOURCE_DISAPPEARING"},"uri":"/serviceProvider/admin/location"}
		// {"notification":{"lifecycle":"RESOURCE_DISAPPEARING"},"uri":"/serviceProvider/admin/icon"}
		// {"notification":{"lifecycle":"RESOURCE_DISAPPEARING"},"uri":"/serviceProvider/admin/friendlyName"}
		// {"notification":{"lifecycle":"RESOURCE_DISAPPEARING"},"uri":"/serviceProvider/admin/bridge"}
		// {"notification":{"lifecycle":"SERVICE_DISAPPEARING"},"uri":"/serviceProvider/admin"}
		// {"notification":{"lifecycle":"RESOURCE_DISAPPEARING"},"uri":"/serviceProvider/tostService/TestProperty"}
		// {"notification":{"lifecycle":"SERVICE_DISAPPEARING"},"uri":"/serviceProvider/tostService"}
		// {"notification":{"lifecycle":"PROVIDER_DISAPPEARING"},"uri":"/serviceProvider"}
		assertEquals(8, this.testContext.getAgentCallbackCount());
	}

	@Test
	public void testSecuredAccess() throws Exception {
		ServiceImpl service = this.testContext.getModelInstance().getRootElement().addService("testService");

		service.addLinkedResource(LocationResource.LOCATION, this.testContext.getModelInstance().getRootElement()
				.getAdminService().getResource(LocationResource.LOCATION));

		ResourceImpl r4impl = service.getResource("location");

		r4impl.registerExecutor(AccessMethod.Type.valueOf(AccessMethod.GET), new Class<?>[0], new String[0],
				new AccessMethodExecutor() {
					@Override
					public Void execute(AccessMethodResponseBuilder result) throws Exception {
						JSONObject jsonObject = (JSONObject) result.getAccessMethodObjectResult();

						jsonObject.put("value",
								new StringBuilder().append(jsonObject.get("value")).append("_suffix").toString());

						result.setAccessMethodObjectResult(jsonObject);
						return null;
					}
				}, AccessMethodExecutor.ExecutionPolicy.AFTER);

		String attributeValue = (String) r4impl.getAttribute("value").setValue("0:0");
		Session session = this.testContext.getSensiNact().getAnonymousSession();

		Resource r4 = session.resource("serviceProvider", "testService", "location");

		Assert.assertNotNull(r4);

		StringBuilder buffer = new StringBuilder();
		buffer.append(attributeValue);
		buffer.append("_suffix");

		GetResponse response = r4.get(DataResource.VALUE);
		String value = (String) response.getResponse().opt(DataResource.VALUE);
		assertEquals(buffer.toString(), value);

		r4 = session.resource("serviceProvider", "admin", "location");
		response = r4.get(DataResource.VALUE);
		value = (String) response.getResponse().opt(DataResource.VALUE);
		assertFalse(buffer.toString().equals(value));
	}

	@Test(expected = InvalidValueException.class)
	public void testConstrained() throws Exception {
		ServiceImpl service = this.testContext.getModelInstance().getRootElement().addService("testService");

		ResourceImpl r2impl = service.addDataResource(PropertyResource.class, "TestProperty2", String.class, null);

		Executable<Void, Object> extractor = service.getResourceValueExtractor("TestProperty2");

		Attribute valueAttribute = r2impl.getAttribute(DataResource.VALUE);
		valueAttribute
				.addMetadata(new Metadata(this.testContext.getMediator(), Metadata.CONSTRAINTS, Constraint[].class,
						new Constraint[] { new MinLength(this.testContext.getMediator().getClassLoader(), 5, false),
								new MaxLength(this.testContext.getMediator().getClassLoader(), 10, false)

						}, Modifiable.FIXED));
		try {
			valueAttribute.setValue("not much");

		} catch (InvalidValueException e) {
			fail("should have complied constraints");
		}
		assertEquals("not much", extractor.execute(null));
		valueAttribute.setValue("too much characters");
		fail("MaxLength constraint fails");
	}

	@Test
	public void testDynamicAdded() throws Exception {
		ServiceImpl service = this.testContext.getModelInstance().getRootElement().addService("testService");

		ServiceProvider proxy = this.testContext.getModelInstance().getRootElement().getProxy(this.tree);

		List<Service> services = proxy.getServices();
		Assert.assertEquals(2, services.size());

		this.testContext.getModelInstance().getRootElement().addService("dynamicService");

		services = proxy.getServices();
		Assert.assertEquals(3, services.size());

		service.addDataResource(PropertyResource.class, "dynamicResource", String.class, "dynamic");
		assertNotNull(proxy.getService("testService").getResource("dynamicResource"));
	}

	@Test
	public void testLinkedAction() throws Exception {
		ServiceImpl service = this.testContext.getModelInstance().getRootElement().addService("testService");

		ResourceImpl action = service.addActionResource("action", ActionResource.class);

		final AtomicInteger counter = new AtomicInteger(0);

		action.registerExecutor(new Signature(this.testContext.getMediator(),
				AccessMethod.Type.valueOf(AccessMethod.ACT), new Class<?>[] { int.class }, new String[] { "count" }),
				new AccessMethodExecutor() {

					@Override
					public Void execute(AccessMethodResponseBuilder parameter) throws Exception {
						int count = (Integer) parameter.getParameter(0);
						for (int i = 0; i < count; i++) {
							counter.incrementAndGet();
						}
						return null;
					}
				}, AccessMethodExecutor.ExecutionPolicy.AFTER);

		action.registerExecutor(
				new Signature(this.testContext.getMediator(), AccessMethod.Type.valueOf(AccessMethod.ACT),
						new Class<?>[] { int.class, boolean.class }, new String[] { "count", "plus" }),
				new AccessMethodExecutor() {

					@Override
					public Void execute(AccessMethodResponseBuilder parameter) throws Exception {
						int count = (Integer) parameter.getParameter(0);
						boolean plus = (Boolean) parameter.getParameter(1);
						if (plus) {
							for (int i = 0; i < count; i++) {
								counter.incrementAndGet();
							}
						} else {
							for (int i = 0; i < count; i++) {
								counter.decrementAndGet();
							}
						}
						return null;
					}
				}, AccessMethodExecutor.ExecutionPolicy.AFTER);

		service.addLinkedActionResource("linkedAction", action, true);

		ResourceImpl emptyLinkedAction = service.addLinkedActionResource("emptyLinkedAction", action, false);

		Method method = ResourceImpl.class.getDeclaredMethod("getAccessMethod", AccessMethod.Type.class);
		method.setAccessible(true);
		LinkedActMethod linkedActMethod = (LinkedActMethod) method.invoke(emptyLinkedAction,
				AccessMethod.Type.valueOf(AccessMethod.ACT));

		method = LinkedActMethod.class.getDeclaredMethod("createShortcut",
				new Class<?>[] { Signature.class, Shortcut.class });
		method.setAccessible(true);

		method.invoke(linkedActMethod,
				new Object[] {
						new Signature(this.testContext.getMediator(), AccessMethod.Type.valueOf(AccessMethod.ACT),
								new Class<?>[] { int.class }, new String[] { "count" }),
						new Shortcut(this.testContext.getMediator(), AccessMethod.Type.valueOf(AccessMethod.ACT),
								new Class<?>[0], new String[0], new HashMap<Integer, Parameter>() {
									{
										this.put(0, new Parameter(TestResourceBuilder.this.testContext.getMediator(),
												"count", int.class, 4));
									}
								}) });

		// securedAccess.getAnonymousSession().registered(instance);
		// instance.getServiceProvider().start();

		ServiceProvider proxy = (ServiceProvider) this.testContext.getModelInstance().getRootElement()
				.getProxy(this.tree);
		Service testService = proxy.getService("testService");

		ActionResource resource = testService.<ActionResource>getResource("action");
		ActionResource linkedResource = testService.<ActionResource>getResource("linkedAction");
		ActionResource emptyLinkedResource = testService.<ActionResource>getResource("emptyLinkedAction");

		assertEquals(0, counter.get());
		resource.act(5).getJSON();
		assertEquals(5, counter.get());
		resource.act(4, false).getJSON();
		assertEquals(1, counter.get());
		linkedResource.act(2).getJSON();
		assertEquals(3, counter.get());
		linkedResource.act(1, false).getJSON();
		assertEquals(2, counter.get());
		emptyLinkedResource.act().getJSON();
		assertEquals(6, counter.get());
		assertEquals(emptyLinkedResource.act(2).getStatus(), AccessMethodResponse.Status.ERROR);
		assertEquals(6, counter.get());
		assertEquals(emptyLinkedResource.act(2, false).getStatus(), AccessMethodResponse.Status.ERROR);
		assertEquals(6, counter.get());
	}

	@Test
	public void testTrigger() throws Throwable {
		ServiceImpl service = this.testContext.getModelInstance().getRootElement().addService("testService");

		ResourceImpl r1impl = service.addActionResource("TestAction", ActionResource.class);

		ResourceImpl r2impl = service.addDataResource(StateVariableResource.class, "TestVariable", String.class,
				"untriggered");

		service.addTrigger("TestAction", "TestVariable",
			new Signature(this.testContext.getMediator(), AccessMethod.Type.valueOf(AccessMethod.ACT), null, null),
				new Constant("triggered", false), AccessMethodExecutor.ExecutionPolicy.AFTER);

		// test locked
		try {
			r2impl.set("triggered");
			fail("Attribute should be locked");

		} catch (Exception e) {
			// e.printStackTrace();
		}
		// securedAccess.getAnonymousSession().registered(instance);
		// instance.getServiceProvider().start();
		// test trigger
		assertEquals("untriggered", r2impl.getAttribute(DataResource.VALUE).getValue());
		ActionResource proxy = (ActionResource) r1impl.getProxy(this.tree);
		proxy.act();
		assertEquals("triggered", r2impl.getAttribute(DataResource.VALUE).getValue());
	}

	@Test
	public void testFiltering() throws Throwable {
		ServiceImpl service = this.testContext.getModelInstance().getRootElement().addService("testService");

		ResourceImpl r1impl = service.addActionResource("TestAction", ActionResource.class);

		ResourceImpl r2impl = service.addDataResource(StateVariableResource.class, "TestVariable", String.class,
				"untriggered");

		Session s = testContext.getSensiNact().getAnonymousSession();
		Thread.sleep(1000);		
		String obj = s.getAll(
				new FilteringCollection(this.testContext.getMediator(), false, new FilteringDefinition("xfilter", "a")))
				.getJSON();

		JSONAssert.assertEquals(
				new JSONObject("{\"providers\":" + "[{\"locXtion\":\"45.19334890078532:5.706474781036377\","
						+ "\"services\":[{\"resources\":" + "[{\"type\":\"PROPERTY\",\"nXme\":\"friendlyNXme\"},"
						+ "{\"type\":\"PROPERTY\",\"nXme\":\"locXtion\"},"
						+ "{\"type\":\"PROPERTY\",\"nXme\":\"bridge\"}," + "{\"type\":\"PROPERTY\",\"nXme\":\"icon\"}],"
						+ "\"nXme\":\"Xdmin\"}," + "{\"resources\":" + "[{\"type\":\"ACTION\",\"nXme\":\"TestAction\"},"
						+ "{\"type\":\"STATE_VARIABLE\",\"nXme\":\"TestVXriXble\"}],"
						+ "\"nXme\":\"testService\"}],\"nXme\":\"serviceProvider\"}],"
						+ "\"filters\":[{\"definition\":\"a\",\"type\":\"xfilter\"}]"
						+ ",\"statusCode\":200,\"type\":\"COMPLETE_LIST\"}"),
				new JSONObject(obj), false);
	}
}
