package IndexManagement;


import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.axis.message.addressing.Address;
import org.apache.axis.message.addressing.EndpointReferenceType;
import org.gcube.common.core.contexts.GCUBERemotePortTypeContext;
import org.gcube.common.core.contexts.GHNContext;
import org.gcube.common.core.informationsystem.client.AtomicCondition;
import org.gcube.common.core.informationsystem.client.ISClient;
import org.gcube.common.core.informationsystem.client.queries.GCUBEGenericResourceQuery;
import org.gcube.common.core.resources.GCUBEGenericResource;
import org.gcube.common.core.scope.GCUBEScope;
import org.gcube.metadatamanagement.metadatabroker.stubs.MetadataBrokerPortType;
import org.gcube.metadatamanagement.metadatabroker.stubs.Transform;
import org.gcube.metadatamanagement.metadatabroker.stubs.TransformationParameter;
import org.gcube.metadatamanagement.metadatabroker.stubs.service.MetadataBrokerServiceAddressingLocator;
import org.gridforum.jgss.ExtendedGSSCredential;
import org.gridforum.jgss.ExtendedGSSManager;
import org.ietf.jgss.GSSCredential;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import IndexManagement.VOInfoManager.CollectionInfo;
import IndexManagement.VOInfoManager.MetadataCollectionInfo;

/* 
 * Run: Col_2_ftRowsetRS <scope> <credentialFile> <metadataCollectionName> <schemaName> <language>
 */

public class Col_2_ftRowsetRS {

	public static void main(String args[]) {
		GSSCredential cred=null;
		String colID = null;
		VOInfoManager VOManager = null;
		
		/* Get the metadata collection ID from the collection name */
		try {
			String VOFileName = args[0].replace("/", "_") + ".properties";
			VOManager = new VOInfoManager(VOFileName);
			CollectionInfo colInfo = VOManager.findCollectionByName(args[2]);
			if (colInfo == null) {
				System.out.println("Collection not found in VO properties.");
				System.exit(-1);
			}
			MetadataCollectionInfo mcInfo = colInfo.findMetadataCollection(args[3], args[4]);
			if (mcInfo == null) {
				System.out.println("Collection not found in VO properties.");
				System.exit(-1);
			}
			colID = mcInfo.getID();
		} catch (Exception e) {
			System.out.println("Failed to parse VO properties file: " + e);
			System.exit(-1);
		}
		
		try {
			//cred=getCredFromFile(args[0]);

			String TPID = getTPIDFromTPName("BrokerTP_" + args[3] + "Col_anylanguage_2_ftRowsetRS_anylanguage", 
					cred,
					GCUBEScope.getScope(args[0]));

			// Create endpoint reference to service
			EndpointReferenceType endpoint = new EndpointReferenceType();
			endpoint.setAddress(new Address(VOManager.getMetadataBrokerURI()));
			MetadataBrokerPortType broker = new MetadataBrokerServiceAddressingLocator().getMetadataBrokerPortTypePort(endpoint);
			broker = GCUBERemotePortTypeContext.getProxy(broker, GCUBEScope.getScope(args[0]));
			
			// Create a set of transformation parameters, assigning values to variables
			// defined in the transformation program
			Transform transParams = new Transform();
			TransformationParameter[] params = new TransformationParameter[1];
			params[0] = new TransformationParameter();
			params[0].setPathToVariable("//Input[@name='TPInput']/Reference");
			params[0].setValue(colID);	
			transParams.setParameters(params);
			
			// Set the transformation program ID
			transParams.setTransformationProgramID(TPID);
			
			// Invoke the remote operation
			String outRS_EPR = broker.transform(transParams);
			System.out.println(outRS_EPR);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Helper method to get a GSSCredential object from a given file
	 * @param filename file containing the (VOMS) credentials
	 * @return the corresponding GSSCredential object
	 * @throws Exception on error
	 */
	private static GSSCredential getCredFromFile(String filename) throws Exception {
 
		GSSCredential retcred = null;
 
		try {
			File inFile = new File(filename);
			byte [] data = new byte[(int)inFile.length()];
			FileInputStream inStream = new FileInputStream(inFile);
			inStream.read(data);
			inStream.close();
			ExtendedGSSManager manager =(ExtendedGSSManager)ExtendedGSSManager.getInstance();
			retcred = manager.createCredential(data,ExtendedGSSCredential.IMPEXP_OPAQUE,GSSCredential.DEFAULT_LIFETIME,null/*use default mechanism - GSI*/,GSSCredential.INITIATE_AND_ACCEPT);
		} catch (Exception e) {
			throw e;
		}
		return retcred;
	}
	
	private static String getTPIDFromTPName(String TPName, GSSCredential cred, GCUBEScope scope) throws Exception {
		ISClient client = GHNContext.getImplementation(ISClient.class);
		GCUBEGenericResourceQuery query = client.getQuery(GCUBEGenericResourceQuery.class);
		query.addAtomicConditions(new AtomicCondition("/Profile/Name", TPName));
		List<GCUBEGenericResource> result = client.execute(query, scope);
		if (result==null || result.size()==0)
			throw new Exception("Transformation program not found.");

		return result.get(0).getID();
	}
	
	/**
	 * Parses an XML string and transforms it to a DOM tree.
	 * 
	 * @param XMLdoc The XML string to parse
	 * @return A Document object describing the DOM tree
	 * @throws ParserConfigurationException an error occured
	 * @throws SAXException an error occured
	 * @throws IOException an error occured
	 */
	private static Document parseXMLString(String XMLdoc) throws ParserConfigurationException, SAXException, IOException  {
		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = dbFactory.newDocumentBuilder();
		return builder.parse(new InputSource(new StringReader(XMLdoc)));
	}
}
