package eu.dnetlib.enabling.tools;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import javax.xml.transform.stream.StreamResult;
import javax.xml.ws.Endpoint;
import javax.xml.ws.wsaddressing.W3CEndpointReference;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.cxf.bus.CXFBusFactory;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.mockito.Mockito.*; // NOPMD

import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
import eu.dnetlib.soap.cxf.CxfEndpointReferenceBuilder;
import eu.dnetlib.soap.cxf.JaxwsEndpointReferenceBuilder;

/**
 * jaxws service resolution.
 * 
 * @author marko
 * 
 */

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "local-cxf.xml")
public class JaxwsServiceResolverImplTest {
	/**
	 * logger. 
	 */
	private static final Log log = LogFactory.getLog(JaxwsServiceResolverImplTest.class); // NOPMD by marko on 11/24/08 5:02 PM
	
	/**
	 * instance under test.
	 */
	private transient JaxwsServiceResolverImpl resolver;

	/**
	 * epr builder.
	 */
	private transient JaxwsEndpointReferenceBuilder eprBuilder;
	
	/**
	 * resultset mock.
	 */
	private transient ResultSetService resultSetService;

	/**
	 * cleanup cxf. This test requires the local transport (declared in local-cxf.xml), 
	 * but other tests may have already instantiated the cxf bus singleton.
	 */
	@BeforeClass
	public static void resetCxf() {
		CXFBusFactory.getDefaultBus().shutdown(true);
	}
	
	/**
	 * common.
	 */
	@Before
	public void setUp() {
		resolver = new JaxwsServiceResolverImpl();
		eprBuilder = new JaxwsEndpointReferenceBuilder();
		eprBuilder.setBuilder(new CxfEndpointReferenceBuilder());
		
		resultSetService = mock(ResultSetService.class);
	}

	/**
	 * get service.
	 * @throws ResultSetException shoudn't happen
	 */
	@Test
	public void testGetService() throws ResultSetException {
		final String rsId = "1235"; 
		
		when(resultSetService.identify()).thenReturn("foo");
		when(resultSetService.getNumberOfElements(rsId)).thenReturn(2);
		
		final Endpoint endpoint = Endpoint.publish("local://test", resultSetService);
		
		assertNotNull("check endpoint", endpoint);
		
		final W3CEndpointReference epr = eprBuilder.getEndpointReference(endpoint, rsId); 

		epr.writeTo(new StreamResult(System.out));
		
		final ResultSetService rset = resolver.getService(ResultSetService.class, epr);		
		
		assertNotNull("check resultset", rset);
		
		log.info(rset.getClass());
		log.info(rset);
		
		assertEquals("check resultset communication", "foo",  rset.identify());
		
		assertEquals("check resolver resource id", rsId, resolver.getResourceIdentifier(epr));
		
		assertEquals("check resultset communication with param", 2, rset.getNumberOfElements(resolver.getResourceIdentifier(epr)));
	}
}
