/**
 * 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.das;

import static org.junit.Assert.assertNotNull;

import java.util.ArrayList;
import java.util.Iterator;
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 eu.dnetlib.data.sts.ds.DepotServiceException;
import eu.dnetlib.data.sts.ds.IDepotService;
import eu.dnetlib.enabling.resultset.rmi.ResultSetException;
import eu.dnetlib.enabling.resultset.rmi.ResultSetService;
import eu.dnetlib.enabling.tools.JaxwsServiceResolverImpl;
import eu.dnetlib.enabling.tools.ServiceResolver;

/**
 * The Class SimpleClient.
 * 
 * @author <a href="mailto:marek.imialek at uni-bielefeld.de">Marek Imialek</a>
 */
public class SimpleClient {

	/** The ctx. */
	//private ApplicationContext ctx;
	
	/** The lls storage. */
	//private ILLSStoreFacade llsStoreFacade;
	
	private IDepotService dS;
		
	private ResultSetService daRS;

	private IDataAccessService daS;
	
	String ip = "146.48.122.27";
	//String ip= "localhost";
	private transient String depotServiceAddress = "http://"+ip+":8980/dnet-sts-ds/services/DepotService";
	private transient String accessServiceAddress = "http://"+ip+":8780/dnet-sts-das/services/DataAccessService";
	private transient String accessServiceRSAddress = "http://"+ip+":8780/dnet-sts-das/services/DataAccessResultSet";
	//private transient String downloadServiceAddress ="";// "http://localhost:8580/dnet-download/services/DownloadService";
	//private transient String fesServiceAddress = "http://"+ip+":8680/dnet-fes/services/FeatureExtractionService";

	/**
	 * Sets the up.
	 * 
	 */
	@Before 
	public void setUp() {
		
		//ctx = SpringUtils
		//	.getSpringContext(SpringUtils.DEFAULT_JUNIT_RESOURCE_DAS);
		//this.llsStoreFacade = (LLSStoreFacade) this.ctx.getBean("ossStorage");
			
		JaxWsProxyFactoryBean factory0 = new JaxWsProxyFactoryBean();
		factory0.setServiceClass(IDepotService.class);
		factory0.setAddress(depotServiceAddress);
		//factory0.setAddress(
			//"http://129.70.40.102:8380/dnet-sts-ds/services/DepotService");
		//dS = (IDepotService) factory0.create();
		
		
		JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
		factory.setServiceClass(ResultSetService.class);
		factory.setAddress(accessServiceRSAddress);
		//factory.setAddress(
			//	"http://129.70.40.102:8480/dnet-sts-das/services/DataAccessResultSet");
		
		daRS = (ResultSetService) factory.create();
		assertNotNull(daRS.identify());
		System.out.println("Identify Read from RS: " + daRS.identify() );
		
		JaxWsProxyFactoryBean factory1 = new JaxWsProxyFactoryBean();
		factory1.setServiceClass(IDataAccessService.class);
		factory1.setAddress(accessServiceAddress);
		//factory1.setAddress(
			//	"http://129.70.40.102:8480/dnet-sts-das/services/DataAccessService");
		daS = (IDataAccessService) factory1.create();
		assertNotNull(daS.identify());
		System.out.println("Identify DA Service: " + daS.identify() );
			
	}
	
	@Test
	public void  testStoreLookUpRS() throws Exception {
		
		//String structureID = creatStructure();
	    //storeObject(structureID);
	    //System.out.println("DS: "+structureID);
		//String structureID = "889d4517-5de3-4e2a-9788-c8739b7ff737_U3RvcmVEU1Jlc291cmNlcy9TdG9yZURTUmVzb3VyY2VUeXBl";
		//String structureID = "e8be38bd-f2ff-47cb-9a2e-e98ccac095c0_U3RvcmVEU1Jlc291cmNlcy9TdG9yZURTUmVzb3VyY2VUeXBl";
		String structureID = "84e4250e-1043-41f8-bf94-ff50451b692a_U3RvcmVEU1Jlc291cmNlcy9TdG9yZURTUmVzb3VyY2VUeXBl";
	    Thread.sleep(3000);
	    
	    W3CEndpointReference downloadEPR = 
			daS.storeLookUpRS(structureID);
		
		printRS(downloadEPR);
	}
	
	@Test
	public void  testStoreLookUpDataRS() throws Exception {
		
		String structureID = creatStructure();
		storeObject(structureID);
		//String structureID = "889d4517-5de3-4e2a-9788-c8739b7ff737_U3RvcmVEU1Jlc291cmNlcy9TdG9yZURTUmVzb3VyY2VUeXBl";
		//String structureID = "dfb0094b-aeb8-4368-82cf-2f8ef3b4365d_U3RvcmVEU1Jlc291cmNlcy9TdG9yZURTUmVzb3VyY2VUeXBl";
		
		Thread.sleep(2000);
		W3CEndpointReference downloadEPR = 
			daS.storeLookUpDataRS(structureID);
		
		printRS(downloadEPR);
		
	}
	
	String myid ="saas";
	@Test
	public void  testStoreLookUpSDORS() throws Exception {
		
		String structureID = creatStructure();
		//String structureID = "1090b589-a255-4515-8b98-a9dc9af22518_U3RvcmVEU1Jlc291cmNlcy9TdG9yZURTUmVzb3VyY2VUeXBl";
	    storeObject(structureID);
		//String structureID = "889d4517-5de3-4e2a-9788-c8739b7ff737_U3RvcmVEU1Jlc291cmNlcy9TdG9yZURTUmVzb3VyY2VUeXBl";
	    //String structureID = "dfb0094b-aeb8-4368-82cf-2f8ef3b4365d_U3RvcmVEU1Jlc291cmNlcy9TdG9yZURTUmVzb3VyY2VUeXBl";
	    //
	    System.out.println(structureID);
	    Thread.sleep(2000);
	    
	    //String sdo = daS.getObjectUrl(myid, structureID);
		//assertNotNull(sdo);
		//System.out.println("Url:" +sdo);
		
		//String sdo1 = daS.getObjectSDO(myid,structureID);
		//assertNotNull(sdo1);
		//System.out.println("SDO:" +sdo1);
	    
	    
	    Thread.sleep(2000);
		System.out.println(structureID);
		W3CEndpointReference downloadEPR = 
			daS.storeLookUpSDORS(structureID);
		
		System.out.println("1th PRINT");
		printRS(downloadEPR);
	
		
		this.deleteObjects(structureID);
		
		Thread.sleep(2000);
		
	
		W3CEndpointReference downloadEPR1 = 
			daS.storeLookUpSDORS(structureID);
		System.out.println("2nd PRINT");
		printRS(downloadEPR1);
		
	/*	storeObject(structureID);
		Thread.sleep(2000);
		
		W3CEndpointReference downloadEPR3 = 
			daS.storeLookUpSDORS(structureID);
		
		System.out.println("3rd PRINT");
		printRS(downloadEPR3);
		*/
	}
	
	@Test
	public void testGetObjectSDO() throws Exception{
	
		String storeDataStructureId = creatStructure();
		storeObject(storeDataStructureId);
		Thread.sleep(2000);
		String sdo = daS.getObjectSDO(myid,storeDataStructureId);
		assertNotNull(sdo);
		System.out.println("SDO:" +sdo);
	}
	
	@Test
	public void testGetObjectUrl() throws Exception{
	
		String storeDataStructureId = creatStructure();
		storeObject(storeDataStructureId);
		Thread.sleep(2000);
		String sdo = daS.getObjectUrl(myid,storeDataStructureId);
		assertNotNull(sdo);
		System.out.println("Url:" +sdo);
	}
	
	
	private void printRS (W3CEndpointReference downloadEPR) throws ResultSetException {
		
		final ServiceResolver serviceResolver2 = new JaxwsServiceResolverImpl();
		final String downloadServiceRsId = serviceResolver2.getResourceIdentifier(downloadEPR);
		
		int resultsNumber = daRS.getNumberOfElements(downloadServiceRsId);
		System.out.println(downloadServiceRsId);
		System.out.println("Number of results in Download RS: "+ resultsNumber);
		System.out.println("RS Status:" + daRS.getRSStatus(downloadServiceRsId));
		
		int pageSize = 10;
		int pages = resultsNumber/pageSize;
		//if (resultsNumber/pageSize > 0) 
			//pages++;
	
		for (int i = 0; i<= pages * pageSize; i= i+pageSize) {
			System.out.print("Getting Page: " + i);
			
			int from = i+1;
			int to = i+pageSize;
			if (to>resultsNumber)
				to = resultsNumber;
			
			System.out.print(" for range "+from +" - " + to);
			System.out.println();
			List<String> results = daRS.getResult(downloadServiceRsId,
					from, to , "waiting");
		
			if (results != null ){
				Iterator<String> iter = results.iterator();
	
				while (iter.hasNext())
					System.out.println("Object: " + iter.next());	
			}
			else {
				System.out.println("Page "+i+" not returned!");
			}
		}	
	}
  
	private String creatStructure() throws Exception {
		System.out.println("\nSTORE OBJECTS");
		
		//String storeDataStructureId = "lookUpStructure";
		//llsStoreFacade.createStoreDataStructure(storeDataStructureId);
		
		List<String> mimeTypes = new ArrayList<String>();
		mimeTypes.add("text/plain");
		String storeDataStructureId = dS.createStore(mimeTypes, 200);
		
		return storeDataStructureId;
	}
	
	private void storeObject(String storeDataStructId) throws Exception {

		
		List<String> objectsForStoring = new ArrayList<String>();
		objectsForStoring.add(
				"<storeRecord><storeRecordIdentifier>"+myid+"</storeRecordIdentifier>" +
				"<storeObject datatype=\"Data\">AAAAAAAAAAeweAjjhjhjhjjjjjhhuyuy</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>");
		
		dS.storeObjects(storeDataStructId, objectsForStoring, "INCREMENTAL");
		/*
		
		String dummyObjectPath = "/tmp/dummyObject";
		String dummyObjectPath2 = "/tmp/dummyObject2";
		File file = new File(dummyObjectPath);
		File file2 = new File(dummyObjectPath2);
		
		try {
			if (!file.exists())
				assertTrue("Can not create file " +
						"required for testing: "  +
						dummyObjectPath,file.createNewFile());
			
		    BufferedWriter out = new BufferedWriter(
		    		new FileWriter(dummyObjectPath));
		    out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
				"<GGGGGGGGG><juhb> hvgvgc gfgc  gg g </juhb></GGGGGGGGG>");
		    out.close();
		    
		    if (!file2.exists())
				assertTrue("Can not create file " +
						"required for testing: "  +
						dummyObjectPath,file2.createNewFile());
			
		    BufferedWriter out2 = new BufferedWriter(
		    		new FileWriter(dummyObjectPath2));
		    out2.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
				"<ROOT><mytag> I am the second object </mytag></ROOT>");
		    out2.close();
			
			//Store first object //
			SimpleDigitalObject sdo = new SimpleDigitalObject();
			sdo.setDataStructureType(DepotServiceConstants.
					STORE_DATA_STRUCTURE_SUBTYPE_OBJECTS);	
			sdo.setObjectLocation(
					FileUtils.convertStreamToByteArray(
							new FileInputStream (dummyObjectPath)));
			sdo.setObjectMimeType("application/xml");
			sdo.setObjectName(file.getName());
			sdo.setObjectExtension("xml");
			String objectId = 
				llsStoreFacade.storeObject(storeDataStructId, sdo);
			assertNotNull(objectId);
			
			//Store second object //
			sdo.setObjectLocation(
					FileUtils.convertStreamToByteArray(
							new FileInputStream (dummyObjectPath2)));
			sdo.setObjectName(file2.getName());
			String objectId2 = 
				llsStoreFacade.storeObject(storeDataStructId, sdo);
			assertNotNull(objectId2);
			
			
		} catch(Exception e) {
			throw new Exception("Nested Exception: " +e);
		} finally {
			//file.delete();
			//llsStoreFacade.removeStoreDataStructure(storeDataStructId);
		}		
		*/
	}
	
	public void deleteObjects (String stId) throws Exception {
		
		List<String> objectsForDeleting = new ArrayList<String>();
		objectsForDeleting.add(myid);
		objectsForDeleting.add("myid2");
		objectsForDeleting.add("myid3");
		/*objectsForDeleting.add("myid4");
		objectsForDeleting.add("myid5");*/
		
		dS.deleteStoreObject(stId, objectsForDeleting);
		
		
		
	}
	
}
