package eu.dnetlib.data.information;

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

import java.util.HashMap;
import java.util.Map;

import javax.xml.ws.wsaddressing.W3CEndpointReference;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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 DataSourceSinkTest {

	private transient DataSinkResolverDispatcher sinkResolver;
	
	/**
	 * 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();

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

	private transient MDStoreDataSinkSourceDescriptorGenerator dataSinkDescriptorGenerator;

	private transient MDStoreDataSinkResolverImpl mdStoreSinkResolver;
	
	private transient String descriptor = "dnet://MDStoreDS/1234?type=REFRESH";
	
	private transient String mdStoreId = "0987654321";
	
	private transient String storageType = "INCREMENTAL";
	
	private transient Map<String, DataSinkResolver> resolverMap = new HashMap<String, DataSinkResolver>();
	
	private static final Log log = LogFactory.getLog(DataSourceSinkTest.class);
	
	/*
	 * based on eu.dnetlib.data.information.MDStoreDataSinkResolverImplTest
	 */
	@Before
	public void setUp(){
		dataSinkDescriptorGenerator = new MDStoreDataSinkSourceDescriptorGenerator();
		
		resolverMap.put("MDStoreDS", new MDStoreDataSinkResolverImpl());
		sinkResolver = new DataSinkResolverDispatcher();
		sinkResolver.setResolvers(resolverMap);
		
		mdStoreSinkResolver = (MDStoreDataSinkResolverImpl)sinkResolver.getResolver(descriptor) ;
		
		lookupLocator = new StaticServiceLocator<ISLookUpService>(lookupService);

		mdStoreSinkResolver.setLookupLocator(lookupLocator);
		mdStoreSinkResolver.setEprBuilder(eprBuilder);
		mdStoreSinkResolver.setServiceResolver(serviceResolver);
		
		try {
			when(lookupService.getResourceProfileByQuery(anyString())).thenReturn("http://somehost/endpoint");
		} catch (ISLookUpDocumentNotFoundException e) {
			log.error(e);
		} catch (ISLookUpException e) {
			log.error(e);
		}

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


	}
	
	@Test
	public void testResolveParameters(){
		//DataSink dataSink = mdStoreSinkResolver.resolve(descriptor);
		MDStoreDataSinkImpl dataSink = (MDStoreDataSinkImpl)mdStoreSinkResolver.resolve(descriptor);
		
		assertNotNull(dataSink);
		assertEquals("1234", dataSink.getMdId());
		assertEquals("REFRESH", dataSink.getStoringType());
		//sinkResolver.resolve(descriptor)
		
	}
	
	@Test
	public void testGenerateParameters(){
		assertEquals("dnet://MDStoreDS/" + mdStoreId + "?type=" + storageType, dataSinkDescriptorGenerator.generateDataSinkDescriptor(mdStoreId, storageType));
	}
}
