package eu.dnetlib.enabling.is.sn.resourcestate;

import static org.junit.Assert.*; // NOPMD
import static org.mockito.Mockito.*; // NOPMD

import org.mockito.ArgumentMatcher;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnit44Runner;

import eu.dnetlib.enabling.is.sn.SubscriptionRequest;

/**
 * test ResourceStateSubscriptionRegistryTest.
 *
 * @author marko
 *
 */
@RunWith(MockitoJUnit44Runner.class)
public class ResourceStateSubscriptionRegistryTest {

	/**
	 * matches.
	 * @author marko
	 *
	 */
	public static class MatchSubscription extends ArgumentMatcher<ResourceStateSubscription> {
		/**
		 * prefix.
		 */
		private final transient String prefix;

		/**
		 * type.
		 */
		private final transient String type;

		/**
		 * resource id.
		 */
		private final transient String resId;

		/**
		 * create a new match subscription checker for a given prefix and a given type.
		 * @param prefix prefix
		 * @param type type
		 * @param resId resource id
		 */
		MatchSubscription(final String prefix, final String type, final String resId) {
			super();
			this.prefix = prefix;
			this.type = type;
			this.resId = resId;
		}
		/**
		 * {@inheritDoc}
		 * @see org.mockito.ArgumentMatcher#matches(java.lang.Object)
		 */
		@Override
		public boolean matches(final Object argument) {
			final ResourceStateSubscription sub = (ResourceStateSubscription) argument;
			return sub.getPrefix().equals(this.prefix) && sub.getType().equals(this.type) && sub.getResourceId().equals(this.resId);
		}

	}

	/**
	 * object under test.
	 */
	private transient ResourceStateSubscriptionRegistry registry;

	/**
	 * DAO mock.
	 */
	@Mock
	private transient ResourceStateSubscriptionDAO subscriptionDao;

	/**
	 * subscription request.
	 */
	private transient SubscriptionRequest sub;

	/**
	 * common setup.
	 */
	@Before
	public void setUp() {
		registry = new ResourceStateSubscriptionRegistry();
		registry.setSubscriptionDao(subscriptionDao);

		sub = new SubscriptionRequest();
	}

	/**
	 * test registration.
	 */
	@Test
	public void testRegisterSubscription() {
		sub.setTopicExpression("CREATE/MyResourceType/123/some/path");
		registry.registerSubscription(sub);
		verify(subscriptionDao).addSubscription(argThat(new MatchSubscription("CREATE", "MyResourceType", "123")));

		sub.setTopicExpression("UPDATE/OtherResourceType");
		registry.registerSubscription(sub);
		verify(subscriptionDao).addSubscription(argThat(new MatchSubscription("UPDATE", "OtherResourceType", "*")));

		sub.setTopicExpression("DELETE/*");
		registry.registerSubscription(sub);
		verify(subscriptionDao).addSubscription(argThat(new MatchSubscription("DELETE", "*", "*")));

		sub.setTopicExpression("CREATE");
		registry.registerSubscription(sub);
		verify(subscriptionDao).addSubscription(argThat(new MatchSubscription("CREATE", "*", "*")));

		assertNotNull("dummy", subscriptionDao);
	}

	/**
	 * test match id.
	 */
	@Test
	public void testMatchId() {
		assertEquals("check pure id", "1234123", registry.matchId("1234123").getPrefix());
		assertEquals("check with suffix", "1234123", registry.matchId("1234123/blabla/blabla").getPrefix());
		assertEquals("check suffix", "/blabla/blabla", registry.matchId("1234123/blabla/blabla").getRest());
	}

}
