package eu.dnetlib.enabling.tools;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.mock; // NOPMD
import static org.mockito.Mockito.when;

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.BusFactory;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
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() {
		BusFactory.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);

		// NOTE: call to identify and getNumberOfElements fail because it seems that the methods are not
		// in the wsdl. This error may be related with the use of mockito and
		// method inheritance of services because there is no such error with
		// non-mocked result set service methods.
		// rset.identify();

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