/**
 * 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 static org.junit.Assert.assertTrue;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
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 org.springframework.context.ApplicationContext;

import eu.dnetlib.data.sts.constants.DepotServiceConstants;
import eu.dnetlib.data.sts.ds.DepotServiceException;
import eu.dnetlib.data.sts.ds.IDepotService;
import eu.dnetlib.data.sts.ds.lls.ILLSStoreFacade;
import eu.dnetlib.data.sts.ds.lls.sdo.SimpleDigitalObject;
import eu.dnetlib.data.sts.lls.LLSStoreFacade;
import eu.dnetlib.data.sts.utils.FileUtils;
import eu.dnetlib.data.sts.utils.SpringUtils;
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;
	
	@SuppressWarnings("unused")
	private IDepotService dS;
		
	private ResultSetService daRS;

	private IDataAccessService daS;

	/**
	 * 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(
				"http://localhost:8980/dnet-sts-ds/services/DepotService");
		dS = (IDepotService) factory0.create();
		*/
		
		JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
		factory.setServiceClass(ResultSetService.class);
		factory.setAddress(
				"http://localhost:8780/dnet-sts-das/services/DataAccessResultSet");
		//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(
				"http://localhost:8780/dnet-sts-das/services/DataAccessService");
		//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 {
		
		List<String> objectType = null;
		
		String structureID = creatStructure();
	    storeObject(structureID);
		//String structureID = "889d4517-5de3-4e2a-9788-c8739b7ff737_U3RvcmVEU1Jlc291cmNlcy9TdG9yZURTUmVzb3VyY2VUeXBl";
		//String structureID = "e8be38bd-f2ff-47cb-9a2e-e98ccac095c0_U3RvcmVEU1Jlc291cmNlcy9TdG9yZURTUmVzb3VyY2VUeXBl";
		
		W3CEndpointReference downloadEPR = 
			daS.storeLookUpRS(structureID, objectType);
		
		printRS(downloadEPR);
	}
	
	@Test
	public void  testStoreLookUpDataRS() throws Exception {
		
		List<String> objectType = null;
		
		String structureID = creatStructure();
		storeObject(structureID);
		//String structureID = "889d4517-5de3-4e2a-9788-c8739b7ff737_U3RvcmVEU1Jlc291cmNlcy9TdG9yZURTUmVzb3VyY2VUeXBl";
		
		W3CEndpointReference downloadEPR = 
			daS.storeLookUpDataRS(structureID, objectType);
		
		printRS(downloadEPR);
	}
	
	@Test
	public void  testStoreLookUpSDORS() throws Exception {
		
		List<String> objectType = null;
		
		String structureID = creatStructure();
	    storeObject(structureID);
		//String structureID = "889d4517-5de3-4e2a-9788-c8739b7ff737_U3RvcmVEU1Jlc291cmNlcy9TdG9yZURTUmVzb3VyY2VUeXBl";
		
		
		W3CEndpointReference downloadEPR = 
			daS.storeLookUpSDORS(structureID, objectType);
		
		printRS(downloadEPR);
	}
	
	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));
		
		for (int i = 1; i<= resultsNumber; i++) {
			System.out.println("Getting Page: " + i);
			
			List<String> results = daRS.getResult(downloadServiceRsId,
					i, i , "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 DepotServiceException {
		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, 0);
		*/
		return storeDataStructureId;
	}
	
	private void storeObject(String storeDataStructId) throws Exception {

		/*
		List<String> objectsForStoring = new ArrayList<String>();
		objectsForStoring.add("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
				"<GGGGGGGGG><juhb> hvgvgc gfgc  gg g </juhb></GGGGGGGGG>");
		objectsForStoring.add("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
				"<ROOT><mytag> I am the second object </mytag></ROOT>");
		dS.storeObjects(storeDataStructId, objectsForStoring, "Data", "REFRESH");
		*/
		
		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);
		}		
		
	}
	
}
