package eu.dnetlib.enabling.manager.msro;

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

import javax.annotation.Resource;

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.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryException;
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
import eu.dnetlib.enabling.tools.ServiceLocator;
import eu.dnetlib.enabling.tools.registration.ServiceRegistrationManagerImpl;
import eu.dnetlib.test.AbstractIntegrationContainerTest;
import eu.dnetlib.test.SpringContextSharer;

/**
 * Test MSRO.
 *
 * @author marko
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
public class MSROClientTest extends AbstractIntegrationContainerTest {

	/**
	 * log.
	 */
	private static final Log log = LogFactory.getLog(MSROClientTest.class); // NOPMD by marko on 11/24/08 5:02 PM

	/**
	 * service registration tick delay.
	 */
	private static final int REG_TICK_DELAY = 100;

	/**
	 * number of service registration ticks.
	 */
	private static final int REGISTRATION_TICKS = 4;

	/**
	 * wait time for executing orchestration workflow.
	 */
	private static final long WAIT_TIME = 5000;

	/**
	 * lookup locator.
	 */
	@Resource
	private transient ServiceLocator<ISLookUpService> lookupLocator;

	/**
	 * registry locator.
	 */
	@Resource
	private transient ServiceLocator<ISRegistryService> registryLocator;

	/**
	 * manager map.
	 */
	private transient ManagerMap managerMap;

	/**
	 * common initialization.
	 */
	@Before
	public void setUp() {
		log.debug("setting up a child context");

		final ApplicationContext context = new ClassPathXmlApplicationContext(
				new String[] { "/eu/dnetlib/enabling/manager/msro/MSROClient-context.xml" }, SpringContextSharer.getGlobalContext());

		managerMap = (ManagerMap) context.getBean("managerMap", ManagerMap.class);
	}

	/**
	 * test validating repository.
	 *
	 * @throws InterruptedException
	 *             could happen
	 * @throws ISRegistryException
	 *             could happen
	 * @throws ISLookUpException
	 *             could happen
	 */
	@Test
	public void testValidateRepostiory() throws InterruptedException, ISRegistryException, ISLookUpException {

		ServiceRegistrationManagerImpl registrationManager = (ServiceRegistrationManagerImpl) SpringContextSharer.getGlobalContext().getBean(
				"mockMDStoreServiceRegistrationManager", ServiceRegistrationManagerImpl.class);
		assertNotNull(registrationManager);

		for (int i = 0; i < REGISTRATION_TICKS; i++) {
			registrationManager.tick();
			Thread.sleep(REG_TICK_DELAY);
		}

		/// mdstore registered.

		String repId = lookupLocator.getService().getResourceProfileByQuery(
				"collection('/db/DRIVER/PendingRepositoryResources/RepositoryServiceResourceType')//RESOURCE_IDENTIFIER/@value/string()");

		registryLocator.getService().validateProfile(repId);

		log.info("repository validated");
		Thread.sleep(WAIT_TIME);

		log.info("check harvesting instance");

		try {
			final String hiId = lookupLocator
					.getService()
					.getResourceProfileByQuery(
							"collection('')//RESOURCE_PROFILE[.//RESOURCE_TYPE/@value/string() = 'HarvestingInstanceDSResourceType']//RESOURCE_IDENTIFIER/@value/string()");

			assertNotNull(hiId);
		} catch (ISLookUpException e) {
			fail("harvesting instance not created:" + e);
		}

	}

	/**
	 * test manager map.
	 * @throws InterruptedException could happen
	 */
	@Test
	public void testManagerMap() throws InterruptedException {
		assertNotNull("dummy", managerMap);

		managerMap.registerIndexForMDStore("123", "456", "DMF", "index");
		managerMap.registerIndexForMDStore("abc", "def", "DMF", "index");

		assertEquals("index for mdstore", "456", managerMap.indexForMDStore("123", "DMF", "index"));
		assertEquals("index for mdstore", "def", managerMap.indexForMDStore("abc", "DMF", "index"));

		assertNull("no index", managerMap.indexForMDStore("xyz", "DMF", "index"));

		managerMap.removeIndex("456");
		assertNull("index removed", managerMap.indexForMDStore("456", "DMF", "index"));

		managerMap.removeMDStore("abc");
		assertNull("mdstore removed", managerMap.indexForMDStore("abc", "DMF", "index"));
	}

}
