package eu.dnetlib.data.information;

import static org.junit.Assert.*;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.*;

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 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;

@RunWith(MockitoJUnit44Runner.class)
public class MDStoreDataSourceResolverImplTest {

	private transient MDStoreDataSourceResolverImpl resolver;
	@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;
	
	@Before
	public void setUp(){
		resolver = new MDStoreDataSourceResolverImpl();
		
		lookupLocator = new StaticServiceLocator<ISLookUpService>(lookupService);
		resolver.setLookupLocator(lookupLocator);
		resolver.setEprBuilder(eprBuilder);
		resolver.setServiceResolver(serviceResolver);
	}
	
	@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);
		
		MDStoreDataSourceImpl dataSource = (MDStoreDataSourceImpl)resolver.resolve("dnet://MDStoreDS/1234");
		
		assertNotNull(dataSource);
		assertEquals("mdId", "1234", dataSource.getMdId());
		assertEquals("from", "", dataSource.getFrom());
		assertEquals("service stub", mdStoreService, dataSource.getMdStoreService());
	}
	
	@Test
	public void testResolveWithFromParameter() 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);
		
		MDStoreDataSourceImpl dataSource = (MDStoreDataSourceImpl)resolver.resolve("dnet://MDStoreDS/1234?from=2009-11-17");
		
		assertNotNull(dataSource);
		assertEquals("mdId", "1234", dataSource.getMdId());
		assertEquals("from", "2009-11-17", dataSource.getFrom());
		assertEquals("service stub", mdStoreService, dataSource.getMdStoreService());
	}
}
