package org.gcube.application.geoportal.utils;

import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;

import java.util.List;

import org.gcube.application.geoportal.model.db.DatabaseConnection;
import org.gcube.application.geoportal.model.fault.ConfigurationException;
import org.gcube.common.encryption.encrypter.StringEncrypter;
import org.gcube.common.resources.gcore.ServiceEndpoint;
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
import org.gcube.resources.discovery.client.api.DiscoveryClient;
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;

public class ISUtils {

	public static DatabaseConnection queryForDB(String platform,String flag) throws ConfigurationException {
		
		SimpleQuery query = queryFor(ServiceEndpoint.class);

		query.addCondition("$resource/Profile/Category/text() eq 'Database'")
		.addCondition("$resource/Profile/Platform/Name/text() eq '"+platform+"'")
		.addCondition("$resource/Profile/AccessPoint//Property[Name/text() eq 'GNA_DB'][Value/text() eq '"+flag+"']")
		.setResult("$resource/Profile/AccessPoint");

		DiscoveryClient<AccessPoint> client = clientFor(AccessPoint.class);
		List<AccessPoint> found=client.submit(query);
		if(found.size()>1) {
			throw new ConfigurationException("Multiple SE found ["+found.size()+"] for platform : "+platform+" flag : "+flag);
		}else if (found.isEmpty()){
			throw new ConfigurationException("No SE found for platform : "+platform+" flag : "+flag);
		}
		AccessPoint point=found.get(0);
		
		
		return new DatabaseConnection(point.username(),decryptString(point.password()),point.address());
		
	}
	
	public static String getToken() throws ConfigurationException {
		SimpleQuery query = queryFor(ServiceEndpoint.class);

		query.addCondition("$resource/Profile/Category/text() eq 'Application'")
		.addCondition("$resource/Profile/Name/text() eq 'GNA-APP'")
		.setResult("$resource/Profile/AccessPoint");

		DiscoveryClient<AccessPoint> client = clientFor(AccessPoint.class);
		
		List<AccessPoint> found= client.submit(query);
		if(found.size()>1) {
			throw new ConfigurationException("Multiple Token SE found ["+found.size()+"] for Category : Application name : GNA-APP");
		}else if (found.isEmpty()){
			throw new ConfigurationException("No Token SE found ["+found.size()+"] for Category : Application name : GNA-APP");
		}
		
		AccessPoint point=found.get(0);
		return decryptString(point.password());
		
	}
	
	
	public static String decryptString(String toDecrypt){
		try{
			return StringEncrypter.getEncrypter().decrypt(toDecrypt);
		}catch(Exception e) {
			throw new RuntimeException("Unable to decrypt : "+toDecrypt,e);
		}
	}
	
	
	public static String getgCubeBaseEndpoint(String category,String name) {
		
		SimpleQuery query = queryFor(ServiceEndpoint.class);

		query.addCondition("$resource/Profile/Category/text() eq '"+category+"'")
		.addCondition("$resource/Profile/Name/text() eq '"+name+"'");
		DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
		
		AccessPoint point=client.submit(query).get(0).profile().accessPoints().asCollection().iterator().next();
		
		return point.address();
	}
	
}
