package eu.dnetlib.enabling.tools.registration;

import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.*; // NOPMD

import javax.xml.ws.Endpoint;

import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import eu.dnetlib.enabling.is.lookup.ISLookUpServiceImpl;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.locators.UniqueServiceLocator;

/**
 * test ValidatingServiceRegistrationManagerImpl.
 *
 * @author marko
 *
 */
@RunWith(MockitoJUnitRunner.class)
public class ValidatingServiceRegistrationManagerImplTest {

	/**
	 * profile id.
	 */
	private static final String PROF_ID = "123";

	/**
	 * validated profile id.
	 */
	private static final String VPROF_ID = "V123";

	/**
	 * fake profile.
	 */
	private static final String PROFILE = "<RESOURCE_PROFILE><HEADER><RESOURCE_KIND value=\"PendingServiceResources\"/></HEADER></RESOURCE_PROFILE>";

	/**
	 * fake profile.
	 */
	private static final String VPROFILE = "<RESOURCE_PROFILE><HEADER><RESOURCE_IDENTIFIER value=\"V123\"/><RESOURCE_KIND value=\"ServiceResources\"/></HEADER></RESOURCE_PROFILE>";

	/**
	 * instance under test.
	 */
	private transient ServiceRegistrationManagerImpl manager;

	/**
	 * registrator mock.
	 */
	@Mock
	private transient ServiceRegistrator registrator;

	/**
	 * is lookup mock.
	 */
	@Mock
	private transient ISLookUpService lookUpService;
	
	@Mock
	private UniqueServiceLocator serviceLocator;
	
	/**
	 * prepare.
	 *
	 * @throws ISLookUpException
	 *             cannot happen
	 */
	@Before
	public void setUp() throws ISLookUpException {
		manager = new ValidatingServiceRegistrationManagerImpl();

		manager.setServiceLocator(serviceLocator);
		manager.setRegistrator(registrator);
		manager.setService(new ISLookUpServiceImpl());

		when(lookUpService.getResourceProfile(PROF_ID)).thenReturn(PROFILE);
		when(lookUpService.getResourceProfile(VPROF_ID)).thenReturn(VPROFILE);
		when(lookUpService.getResourceProfileByQuery(anyString())).thenReturn(PROFILE);
		when(registrator.validateProfile(eq(PROF_ID), any(Endpoint.class))).thenReturn(VPROF_ID);
		when(serviceLocator.getService(ISLookUpService.class)).thenReturn(lookUpService);
		when(serviceLocator.getService(ISLookUpService.class, true)).thenReturn(lookUpService);
	}

	/**
	 * test state machine.
	 *
	 * @throws ISLookUpException
	 *             cannot happen
	 */
	@Test
	@Ignore
	public void testTick() throws ISLookUpException {
		when(registrator.registerService(anyObject(), (Endpoint) anyObject())).thenReturn(PROF_ID);

		assertEquals("check unregistered state", ServiceRegistrationManagerImpl.State.UNKNOWN, manager.getState());
		manager.tick();
		assertEquals("check pending state", ServiceRegistrationManagerImpl.State.PENDING, manager.getState());
		assertEquals("ensure that the mock is correct", "PendingServiceResources", manager.getServiceProfile().getResourceKind());
		manager.tick();

		assertEquals("should register directly", ServiceRegistrationManagerImpl.State.REGISTERED, manager.getState());

		verify(registrator).validateProfile(eq(PROF_ID), (Endpoint) anyObject());

		assertEquals("check validation id", VPROF_ID, manager.getProfileId());
		assertEquals("check validation profile", VPROF_ID, manager.getServiceProfile().getResourceId());

		manager.tick();
		assertEquals("should remain registered", ServiceRegistrationManagerImpl.State.REGISTERED, manager.getState());
	}

}
