package eu.dnetlib.data.information;

import static org.junit.Assert.*;

import javax.xml.ws.wsaddressing.W3CEndpointReference;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.argThat;
import org.mockito.runners.MockitoJUnit44Runner;

import eu.dnetlib.data.mdstore.IMDStoreService;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpDocumentNotFoundException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.tools.ServiceLocator;
import eu.dnetlib.enabling.tools.ServiceResolver;
import eu.dnetlib.enabling.tools.StaticServiceLocator;
import eu.dnetlib.soap.cxf.StandaloneCxfEndpointReferenceBuilder;

/**
 * Tests the DataSinkResolverImpl.
 *
 * @author marko
 *
 */
@RunWith(MockitoJUnit44Runner.class)
public class MDStoreDataSinkResolverImplTest {

	/**
	 * instance under test.
	 */
	private transient MDStoreDataSinkResolverImpl resolver;

	/**
	 * mock mdstore service, used only for checking that the resolver correctly creates the stub.
	 */
	@Mock
	private transient IMDStoreService mdstoreService;

	/**
	 * mock lookup service.
	 */
	@Mock
	private transient ISLookUpService lookupService;

	/**
	 * lookup locator pointing to the mock lookup service.
	 */
	private transient ServiceLocator<ISLookUpService> lookupLocator;

	/**
	 * epr builder.
	 */
	private transient StandaloneCxfEndpointReferenceBuilder eprBuilder = new StandaloneCxfEndpointReferenceBuilder();

	/**
	 * service resolver mock.
	 */
	@Mock
	private transient ServiceResolver serviceResolver;

	/**
	 * common setup.
	 */
	@Before
	public void setUp() {
		resolver = new MDStoreDataSinkResolverImpl();

		lookupLocator = new StaticServiceLocator<ISLookUpService>(lookupService);
		resolver.setLookupLocator(lookupLocator);
		resolver.setEprBuilder(eprBuilder);
		resolver.setServiceResolver(serviceResolver);
	}

	/**
	 * Tests the resolve method.
	 *
	 * @throws ISLookUpDocumentNotFoundException
	 *             mock exception
	 * @throws ISLookUpException
	 *             mock exception
	 */
	@Test
	public void testResolve() throws ISLookUpDocumentNotFoundException, ISLookUpException {
		when(lookupService.getResourceProfileByQuery(anyString())).thenReturn("http://somehost/endpoint");

		when(serviceResolver.getService(eq(IMDStoreService.class), argThat(new ArgumentMatcher<W3CEndpointReference>() {
			@Override
			public boolean matches(Object argument) {
				W3CEndpointReference arg = (W3CEndpointReference) argument;
				return arg.toString().contains("http://somehost/endpoint");
			}
		}))).thenReturn(mdstoreService);

		MDStoreDataSinkImpl sink = (MDStoreDataSinkImpl) resolver.resolve("dnet://MDStoreDS/1234?type=REFRESH");

		assertNotNull(sink);

		assertEquals("mdid", "1234", sink.getMdId());
		assertEquals("type", "REFRESH", sink.getStoringType());
		assertEquals("service stub", mdstoreService, sink.getMdStoreService());
	}

	/**
	 * test the parse descriptor method.
	 */
	@Test
	public void testParseDescriptor() {
		MDStoreParameters res = resolver.parseDescriptor("dnet://MDStoreDS/1234?type=REFRESH");
		assertEquals("mdid", "1234", res.getId());
		assertEquals("type", "REFRESH", res.getParameters().get("type"));
	}

}
