/**
 * Copyright 2008-2009 DRIVER PROJECT (Bielefeld University)
 * Original author: Marek Imialek <marek.imialek at uni-bielefeld.de>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package eu.dnetlib.data.sts.ds;

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

import java.util.ArrayList;
import java.util.List;

import javax.xml.ws.wsaddressing.W3CEndpointReference;

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;

import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
import eu.dnetlib.enabling.tools.JaxwsServiceResolverImpl;
import eu.dnetlib.enabling.tools.ServiceResolver;
import eu.dnetlib.data.sts.utils.SpringUtils;

/**
 * @author <a href="mailto:marek.imialek at uni-bielefeld.de">Marek Imialek</a>
 *
 */
public class DepotServiceFacadeTest {
	
	/*
	private static transient W3CEndpointReference epr;
	@SuppressWarnings("unused")
	private static transient W3CEndpointReference eprLang;
	@SuppressWarnings("unused")
	private static transient JaxwsServiceResolverImpl resolver;

	private static transient JaxwsEndpointReferenceBuilder eprBuilder;
	*/
	//ResultSetService resultSetService;
	
	/** The ctx. */
	private ApplicationContext ctx;
	
	/** The depot service. */
	private IDepotService depotService;

	private ResultSetService resultSetService;
	
	/**
	 * Sets the up.
	 * 
	 * @throws java.lang.Exception 	 * @throws Exception the exception
	 */
	
	@Before
	public void  setUp() throws Exception {
		ctx = SpringUtils
			.getSpringContext(SpringUtils.DEFAULT_JUNIT_RESOURCE);
		depotService = (IDepotService) ctx.getBean("DepotService");
		//resultSetService = (ResultSetService) ctx.getBean("resultSetService");
		
		JaxWsProxyFactoryBean factory0 = new JaxWsProxyFactoryBean();
		factory0.setServiceClass(ResultSetService.class);
		//factory0.setAddress(
		//		"http://146.48.85.160:8280/is/services/resultSet");
		factory0.setAddress(
				"http://129.70.40.103:8090/app/services/resultSet");
		resultSetService = (ResultSetService) factory0.create();
		assertNotNull(resultSetService.identify());
		System.out.println("Identify Push RS: " + resultSetService.identify() );
	}
	
	@Test
	public void identifyTest() {
		System.out.println("IDENTIFY");
		assertNotNull(depotService);
		assertNotNull(depotService.identify());
		System.out.println("Here is my depot identifier: "+ depotService.identify());
		System.out.println();
	}
	
	@Test
	public void createStoreTest() throws Exception {
		System.out.println("CREATE STORE DATA STRUCTURE");
		List<String> predefinedObjectTypes = new ArrayList<String>();
		predefinedObjectTypes.add("application/msword");
		predefinedObjectTypes.add("application/pdf");
		predefinedObjectTypes.add("application/xml");
		long maxSizeStDS = 10;
		
		String storeIdentifer = depotService.createStore(predefinedObjectTypes,maxSizeStDS);
		assertNotNull(storeIdentifer);
		System.out.println("The identifier of new created structure. "+ storeIdentifer);
		System.out.println();
	}
	
	@Test
	public void deleteStoreTest() throws Exception {
		System.out.println("DELETE STORE");
		List<String> predefinedObjectTypes = new ArrayList<String>();
		predefinedObjectTypes.add("application/msword");
		predefinedObjectTypes.add("application/pdf");
		predefinedObjectTypes.add("application/xml");
		long maxSizeStDS = 10;
		
		String storeIdentifer = depotService.createStore(predefinedObjectTypes,maxSizeStDS);
		assertNotNull(storeIdentifer);
		
		System.out.println("Deleting Store Data Structure");
		depotService.deleteStore(storeIdentifer);
		System.out.println();
	}
	
	@Test
	public void updateStoreTest() throws Exception {
		System.out.println("UPDATE STORE");
		List<String> predefinedObjectTypes = new ArrayList<String>();
		predefinedObjectTypes.add("application/msword");
		predefinedObjectTypes.add("application/pdf");
		predefinedObjectTypes.add("application/xml");		
		long maxSizeStDS = 10;
		
		String storeIdentifer = depotService.createStore(predefinedObjectTypes,maxSizeStDS);
		assertNotNull(storeIdentifer);
		
		List<String> predefinedObjectTypesUp = new ArrayList<String>();
		predefinedObjectTypesUp.add("text/html");
		predefinedObjectTypesUp.add("image/jpg");
		long maxSizeStDSUp = 70;

		System.out.println("Update Store Data Structure");
		depotService.updateStore(storeIdentifer, maxSizeStDSUp, predefinedObjectTypesUp);
		
		depotService.deleteStore(storeIdentifer);
		System.out.println();
	}
	
	@Test
	public void storeObjectsTest() throws Exception {
		System.out.println("\nSTORE OBJECTS");
		List<String> predefinedObjectTypes = new ArrayList<String>();
		predefinedObjectTypes.add("application/msword");
		predefinedObjectTypes.add("application/pdf");
		predefinedObjectTypes.add("text/plain");
		long maxSizeStDS = 10;
		//String storeIdentifer = "sts-identifier-0";
		String storeIdentifer = depotService.createStore(predefinedObjectTypes,maxSizeStDS);
		//assertNotNull(storeIdentifer);
		
		System.out.println("STORING OBJECTS");
		List<String> objectsForStoring = new ArrayList<String>();
		
		objectsForStoring.add(
				"<storeRecord><storeRecordIdentifier></storeRecordIdentifier>" +
				"<storeObject datatype=\"Data\">AAAAAAAAAAAjjhjhjhjjjjjhhuyuy</storeObject>" +
				"</storeRecord>");
		objectsForStoring.add(
				"<storeRecord><storeRecordIdentifier>myid2</storeRecordIdentifier>" +
				"<storeObject datatype=\"Data\">BBBBBBBBBBB jbhhjbhbygy hbhbhbhb </storeObject>" +
				"</storeRecord>");
		objectsForStoring.add(
				"<storeRecord><storeRecordIdentifier>myid3</storeRecordIdentifier>" +
				"<storeObject datatype=\"Data\">testeqeqeqwe qdsadd</storeObject>" +
				"</storeRecord>");
		objectsForStoring.add(
				"<storeRecord><storeRecordIdentifier>myid4</storeRecordIdentifier>" +
				"<storeObject datatype=\"Data\">DDDDDDD juhb hvgvgc gfgc  gg g gcg</storeObject>" +
				"</storeRecord>");
		objectsForStoring.add(
				"<storeRecord><storeRecordIdentifier>myid5</storeRecordIdentifier>" +
				"<storeObject datatype=\"Data\">EEEEEEEEE juhb hvgvgc gfgc  gg g gcg</storeObject>" +
				"</storeRecord>");
		
		depotService.storeObjects(storeIdentifer, 
				objectsForStoring, "REFRESH", false);
		
		//List<String> stObjectIds = null;
		//depotService.deleteStoreObject(storeIdentifer, stObjectIds );
	
		//depotService.deleteStore(storeIdentifer);
		System.out.println("Juppi!!! I am out of this job! :) \n");
		System.out.println("Sleeping to give some time for finishing junit job!");
		try {
			Thread.sleep(4000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("WakeUp!");
	}
	
	@Test
	public void storeObjectsTestURIs() throws Exception {
		System.out.println("\nSTORE OBJECTS");
		List<String> predefinedObjectTypes = new ArrayList<String>();
		predefinedObjectTypes.add("application/msword");
		predefinedObjectTypes.add("application/pdf");
		predefinedObjectTypes.add("application/xml");
		predefinedObjectTypes.add("text/html");
		predefinedObjectTypes.add("text/plain");
		long maxSizeStDS = 10;
		//String storeIdentifer = "sts-identifier-0";
		String storeIdentifer = depotService.createStore(predefinedObjectTypes,maxSizeStDS);
		//assertNotNull(storeIdentifer);
		
		System.out.println("STORING OBJECTS");
		List<String> objectsForStoring = new ArrayList<String>();
		objectsForStoring.add(
				"<storeRecord><storeRecordIdentifier>h212121-76767</storeRecordIdentifier>" +
				"<storeObject datatype=\"URI\">http://localhost/index.html</storeObject>" +
				"</storeRecord>");
		objectsForStoring.add(
				"<storeRecord><storeRecordIdentifier>h212121-767671</storeRecordIdentifier>" +
				"<storeObject datatype=\"URI\">http://www.onet.pl/index.html</storeObject>" +
				"</storeRecord>");
		objectsForStoring.add(
				"<storeRecord><storeRecordIdentifier>h212121-767672</storeRecordIdentifier>" +
				"<storeObject datatype=\"URI\">http://www.papirus.pl/download/gazetka.pdf</storeObject>" +
				"</storeRecord>");
		
		depotService.storeObjects(storeIdentifer, 
				objectsForStoring, "REFRESH", true);
		
		//List<String> stObjectIds = null;
		//depotService.deleteStoreObject(storeIdentifer, stObjectIds );
	
		//depotService.deleteStore(storeIdentifer);
		System.out.println("Juppi!!! I am out of this job! :) \n");
		System.out.println("Sleeping to give some time for finishing junit job!");
		try {
			Thread.sleep(25000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("WakeUp!");
	}
	
	@Test
	
	public void storeObjectsFromRSTest() throws Exception {
		System.out.println("\nSTORE OBJECTS");
		assertNotNull(resultSetService.identify());
		
		W3CEndpointReference rsEPR = resultSetService.createPushRS(70, 70);
		
		List<String> objectsForStoring = new ArrayList<String>();
		objectsForStoring.add(
				"<storeRecord><storeRecordIdentifier></storeRecordIdentifier>" +
				"<storeObject datatype=\"Data\">AAAAAAAAAAAjjhjhjhjjjjjhhuyuy</storeObject>" +
				"</storeRecord>");
		objectsForStoring.add(
				"<storeRecord><storeRecordIdentifier>myid2</storeRecordIdentifier>" +
				"<storeObject datatype=\"Data\">BBBBBBBBBBB jbhhjbhbygy hbhbhbhb </storeObject>" +
				"</storeRecord>");
		objectsForStoring.add(
				"<storeRecord><storeRecordIdentifier>myid3</storeRecordIdentifier>" +
				"<storeObject datatype=\"Data\">testeqeqeqwe qdsadd</storeObject>" +
				"</storeRecord>");
		objectsForStoring.add(
				"<storeRecord><storeRecordIdentifier>myid4</storeRecordIdentifier>" +
				"<storeObject datatype=\"Data\">DDDDDDD juhb hvgvgc gfgc  gg g gcg</storeObject>" +
				"</storeRecord>");
		objectsForStoring.add(
				"<storeRecord><storeRecordIdentifier>myid5</storeRecordIdentifier>" +
				"<storeObject datatype=\"Data\">EEEEEEEEE juhb hvgvgc gfgc  gg g gcg</storeObject>" +
				"</storeRecord>");
		
		final ServiceResolver serviceResolver = new JaxwsServiceResolverImpl();
		final ResultSetService resultSetService = serviceResolver.getService(
				ResultSetService.class, rsEPR);
		final String rsId = serviceResolver.getResourceIdentifier(rsEPR);
		resultSetService.populateRS(rsId, objectsForStoring);
		resultSetService.closeRS(rsId);
		
		System.out.println("Number of objects stored in RS: "+ 
				resultSetService.getNumberOfElements(rsId));
		
		List<String> predefinedObjectTypes = new ArrayList<String>();
		predefinedObjectTypes.add("application/msword");
		predefinedObjectTypes.add("application/pdf");
		predefinedObjectTypes.add("text/plain");
		long maxSizeStDS = 10;
		
		String storeIdentifer = depotService.createStore(predefinedObjectTypes,maxSizeStDS);
		assertNotNull(storeIdentifer);
		
		depotService.storeObjectsFromRS(storeIdentifer, 
				rsEPR, "REFRESH", false);
		
		//List<String> stObjectIds = null;
		//depotService.deleteStoreObject(storeIdentifer, stObjectIds );
	
		//depotService.deleteStore(storeIdentifer);
		System.out.println("Juppi!!! I am out of this job! :) \n");
		
		System.out.println("Sleeping to give some time for finishing junit job!");
		try {
			Thread.sleep(10000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("WakeUp!");
		
	}
	
	@Test

	public void storeObjectsFromRSURIsTest() throws Exception {
		System.out.println("\nSTORE URIs");
		
		W3CEndpointReference rsEPR = resultSetService.createPushRS(70, 70);
		
		List<String> objectsForStoring = new ArrayList<String>();
		objectsForStoring.add(
				"<storeRecord><storeRecordIdentifier>h212121-76767</storeRecordIdentifier>" +
				"<storeObject datatype=\"URI\">http://localhost/index.html</storeObject>" +
				"</storeRecord>");
		objectsForStoring.add(
				"<storeRecord><storeRecordIdentifier>h212121-767671</storeRecordIdentifier>" +
				"<storeObject datatype=\"URI\">http://www.onet.pl/index.html</storeObject>" +
				"</storeRecord>");
		objectsForStoring.add(
				"<storeRecord><storeRecordIdentifier>h212121-767672</storeRecordIdentifier>" +
				"<storeObject datatype=\"URI\">http://www.papirus.pl/download/gazetka.pdf</storeObject>" +
				"</storeRecord>");
		final ServiceResolver serviceResolver = new JaxwsServiceResolverImpl();
		final ResultSetService resultSetService = serviceResolver.getService(
				ResultSetService.class, rsEPR);
		final String rsId = serviceResolver.getResourceIdentifier(rsEPR);
		resultSetService.populateRS(rsId, objectsForStoring);
		resultSetService.closeRS(rsId);
		
		System.out.println("Number of objects stored in RS: "+ 
				resultSetService.getNumberOfElements(rsId));
		
		List<String> predefinedObjectTypes = new ArrayList<String>();
		predefinedObjectTypes.add("application/msword");
		predefinedObjectTypes.add("application/pdf");
		predefinedObjectTypes.add("text/html");
		predefinedObjectTypes.add("text/plain");
		long maxSizeStDS = 10;
		
		String storeIdentifer = depotService.createStore(predefinedObjectTypes,maxSizeStDS);
		assertNotNull(storeIdentifer);
		
		depotService.storeObjectsFromRS(storeIdentifer, 
				rsEPR, "REFRESH", false);
		
		//List<String> stObjectIds = null;
		//depotService.deleteStoreObject(storeIdentifer, stObjectIds );
	
		//depotService.deleteStore(storeIdentifer);
		System.out.println("Juppi!!! I am out of this job! :) \n");
		
		System.out.println("Sleeping to give some time for finishing junit job!");
		try {
			Thread.sleep(25000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("WakeUp!");
		
	}
	
	@Test
	public void deleteStoreObjectTest() throws Exception {
		System.out.println("\nDELETE OBJECTS");
		List<String> predefinedObjectTypes = new ArrayList<String>();
		predefinedObjectTypes.add("application/msword");
		predefinedObjectTypes.add("application/pdf");
		predefinedObjectTypes.add("application/xml");
		predefinedObjectTypes.add("text/plain");
		long maxSizeStDS = 10;
		//String storeIdentifer = "sts-identifier-0";
		String storeIdentifer = depotService.createStore(predefinedObjectTypes,maxSizeStDS);
		//assertNotNull(storeIdentifer);
		
		System.out.println("STORING OBJECTS");
		String objectId1 = "myId1";
		String objectId2 = "myId2";
		List<String> objectsForStoring = new ArrayList<String>();
		objectsForStoring.add(
				"<storeRecord><storeRecordIdentifier>"+objectId1+"</storeRecordIdentifier>" +
				"<storeObject datatype=\"Data\">AAAAAAAAAAAjjhjhjhjjjjjhhuyuy</storeObject>" +
				"</storeRecord>");
		objectsForStoring.add(
				"<storeRecord><storeRecordIdentifier>"+objectId2+"</storeRecordIdentifier>" +
				"<storeObject datatype=\"Data\">BBBBBBBBBBB jbhhjbhbygy hbhbhbhb</storeObject>" +
				"</storeRecord>");

		depotService.storeObjects(storeIdentifer, 
				objectsForStoring, "REFRESH", false);
		
	
		//depotService.deleteStore(storeIdentifer);
		System.out.println("Juppi!!! I am out of this job! :) \n");
		System.out.println("Sleeping to give some time for finishing junit job!");
		try {
			Thread.sleep(4000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("WakeUp!");
		
		List<String> stObjectIds = new ArrayList<String>();
		stObjectIds.add(objectId1);
		stObjectIds.add(objectId2);
		depotService.deleteStoreObject(storeIdentifer, stObjectIds);
	}
	
	@Test
	public void storingCallbackTest() throws Exception {
		
		System.out.println("\nSTORING CALLBACK TEST");
		List<String> predefinedObjectTypes = new ArrayList<String>();
		predefinedObjectTypes.add("application/msword");
		predefinedObjectTypes.add("application/pdf");
		predefinedObjectTypes.add("application/xml");
		long maxSizeStDS = 10;
		
		String storeIdentifer = depotService.createStore(predefinedObjectTypes,maxSizeStDS);
		
		String storingStatProfile = 
			depotService.storingCallback(storeIdentifer, null, true);
		System.out.println(storingStatProfile);
		assertNotNull(storingStatProfile);
	}
	
	@Test
	public void updateDASReplicaTest() {
		
		String profile = null;
		try {
			depotService.updateDASReplica("http://ble1.ble1","activate");
			fail("Exception expected, non existing relpica in service profile, can not be activated!");
		} catch (Exception e) {}
			
		try {
			depotService.updateDASReplica("http://ble2.ble2","inactivate");
			fail("Exception expected, non existing relpica in service profile, can not be inactivated!");
		} catch (Exception e) {}
		
		try {
			depotService.updateDASReplica("http://ble2.ble2","delete");
			fail("Exception expected, non existing relpica in service profile, can not be removed!");
		} catch (Exception e) {}
		
		try {
			depotService.updateDASReplica("http://ble2.ble2","somaction");
			fail("Exception expected, no valid action!");
		} catch (Exception e) {}
		
		try {
			profile = depotService.updateDASReplica("http://ble2.ble2", "add");
		} catch (Exception e) {
			fail("Non-expected exception, new DAS can not be registered: "+e);
		}
		if (!profile.contains("http://ble2.ble2"))
			fail("DAS not registered in service profile!");
		
		try {
			profile = depotService.updateDASReplica("http://www.openaire.eu","add");
		} catch (Exception e) {
			fail("Non-expected exception, new DAS can not be registered: "+e);
		}
		if (!profile.contains("http://www.openaire.eu"))
			fail("DAS not registered in service profile!");
		
		try {
			profile = depotService.updateDASReplica("http://146.48.122.30:8780/dnet-sts-das/services/DataAccessService", "delete");
		} catch (Exception e) {
			fail("Non-expected exception, DAS can not be removed: "+e);
		}
		if (profile.contains("http://146.48.122.30:8780/dnet-sts-das/services/DataAccessService"))
			fail("DAS entry not removed from service profile!");
		
		try {
			profile = depotService.updateDASReplica("http://146.48.122.30:8780/dnet-sts-das/services/DataAccessService", "inactivate");
		} catch (Exception e) {
			fail("Non-expected exception, DAS can not be inactivated: "+e);
		}
		
		try {
			profile = depotService.updateDASReplica("http://146.48.122.30:8780/dnet-sts-das/services/DataAccessService", "activate");
		} catch (Exception e) {
			fail("Non-expected exception, DAS can not be activated: "+e);
		}
		
		try {
			profile = depotService.updateDASReplica("http://146.48.122.30:8780/dnet-sts-das/services/DataAccessService", "sync");
		} catch (Exception e) {
			fail("Non-expected exception, DAS can not be synced: "+e);
		}
		
			
	}
	
}
