package org.gcube.portlets.admin.resourcemanagement.shared.resource;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

import org.gcube.common.resources.gcore.ServiceEndpoint;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.informationsystem.model.reference.entities.Facet;
import org.gcube.informationsystem.model.reference.entities.Resource;
import org.gcube.informationsystem.model.reference.relations.ConsistsOf;
import org.gcube.informationsystem.resourceregistry.client.ResourceRegistryClient;
import org.gcube.informationsystem.serialization.ElementMapper;
import org.gcube.resourcemanagement.model.reference.entities.facets.AccessPointFacet;
import org.gcube.resourcemanagement.model.reference.entities.facets.ContactFacet;
import org.gcube.resourcemanagement.model.reference.entities.facets.IdentifierFacet;
import org.gcube.resourcemanagement.model.reference.entities.facets.MemoryFacet;
import org.gcube.resourcemanagement.model.reference.entities.facets.NetworkingFacet;
import org.gcube.resourcemanagement.model.reference.entities.facets.SchemaFacet;
import org.gcube.resourcemanagement.model.reference.entities.facets.SimplePropertyFacet;
import org.gcube.resourcemanagement.model.reference.entities.facets.SoftwareFacet;
import org.gcube.resourcemanagement.model.reference.entities.facets.StateFacet;

import org.gcube.resourcemanagement.model.reference.entities.resources.Actor;
import org.gcube.resourcemanagement.model.reference.entities.resources.LegalBody;
import org.gcube.resourcemanagement.model.reference.entities.resources.Person;

import org.gcube.resourcemanagement.model.reference.entities.resources.ConfigurationTemplate;
import org.gcube.resourcemanagement.model.reference.entities.resources.Configuration;

import org.gcube.resourcemanagement.model.reference.entities.resources.Dataset;
import org.gcube.resourcemanagement.model.reference.entities.resources.ConcreteDataset;

import org.gcube.resourcemanagement.model.reference.entities.resources.Schema;

import org.gcube.resourcemanagement.model.reference.entities.resources.EService;
import org.gcube.resourcemanagement.model.reference.entities.resources.RunningPlugin;
import org.gcube.resourcemanagement.model.reference.entities.resources.HostingNode;
import org.gcube.resourcemanagement.model.reference.entities.resources.VirtualService;

import org.gcube.resourcemanagement.model.reference.entities.resources.Site;

import org.gcube.resourcemanagement.model.reference.entities.resources.Software;
import org.gcube.resourcemanagement.model.reference.entities.resources.Plugin;

import org.gcube.resourcemanagement.model.reference.relations.consistsof.HasPersistentMemory;
import org.gcube.resourcemanagement.model.reference.relations.consistsof.HasVolatileMemory;
import org.gcube.resourcemanagement.model.reference.relations.consistsof.IsIdentifiedBy;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * @author pieve mail:alessandro.pieve@isti.cnr.it
 *
 */
public class UtilityResource {

	private static Logger logger = LoggerFactory.getLogger(UtilityResource.class);

	//TODO
	public static ArrayList<String> getSubResourcesTree(ResourceRegistryClient resourceRegistryClient, String entity,
			String scope) throws Exception {
		ArrayList<String> list = new ArrayList<>();

		String s = resourceRegistryClient.getInstances(entity, true);
		List<Resource> resources = ElementMapper.unmarshalList(Resource.class, s);

		for (Resource r : resources) {
			List<? extends IsIdentifiedBy> iibs = r.getConsistsOf(IsIdentifiedBy.class);
			for (IsIdentifiedBy iib : iibs) {

				Facet f = (Facet) iib.getTarget();

				switch (entity) {
				case "Actor":
					if (f instanceof ContactFacet) {
						logger.info("------------Actor--ContactFacet");
						ContactFacet sf = (ContactFacet) f;
						if (!list.contains(sf.getEMail())) {
							list.add(sf.getEMail());
						}
					}
					break;
				case "LegalBody":
					if (f instanceof ContactFacet) {
						logger.info("------------LegalBody--ContactFacet");
						ContactFacet sf = (ContactFacet) f;
						if (!list.contains(sf.getEMail())) {
							list.add(sf.getEMail());
						}
					}
					break;
				case "Person":
					if (f instanceof ContactFacet) {
						logger.info("------------Person--ContactFacet");
						ContactFacet sf = (ContactFacet) f;
						if (!list.contains(sf.getEMail()))
							list.add(sf.getEMail());
					}
					break;	
				case "ConfigurationTemplate":
					if (f instanceof IdentifierFacet) {
						logger.info("------------ConfigurationTemplate--IdentifierFacet");
						IdentifierFacet sf = (IdentifierFacet) f;
						if (!list.contains(sf.getIdentificationType().toString()))
							list.add(sf.getIdentificationType().toString());
					}
					break;		
				case "Configuration":
					if (f instanceof SoftwareFacet) {
						logger.info("------------Configuration--IdentifierFacet");
						IdentifierFacet sf = (IdentifierFacet) f;
						if (!list.contains(sf.getIdentificationType().toString())) {
							list.add(sf.getIdentificationType().toString());
						}
					}
					break;

				case "Dataset":
					if (f instanceof IdentifierFacet) {
						logger.info("------------Dataset--IdentifierFacet");
						IdentifierFacet sf = (IdentifierFacet) f;
						if (!list.contains(sf.getIdentificationType().toString())) {
							list.add(sf.getIdentificationType().toString());
						}
					}
					break;
				case "ConcreteDataset":
					if (f instanceof IdentifierFacet) {
						logger.info("------------ConcreteDataset--IdentifierFacet");
						IdentifierFacet sf = (IdentifierFacet) f;
						if (!list.contains(sf.getIdentificationType().toString())) {
							list.add(sf.getIdentificationType().toString());
						}
					}
					break;
				case "Schema":
					if (f instanceof SchemaFacet) {
						logger.info("------------Schema--SchemaFacet");
						SchemaFacet sf = (SchemaFacet) f;
						if (!list.contains(sf.getName())) {
							list.add(sf.getName());
						}
					}
					break;

				case "EService": // GcoreEndPoint
					if (f instanceof SoftwareFacet) {
						logger.info(
								"------------EService--SoftwareFacet");
						SoftwareFacet sf = (SoftwareFacet) f;
						if (!list.contains(sf.getGroup()))
							list.add(sf.getGroup());
					}
					break;
				case "RunningPlugin":
					if (f instanceof SoftwareFacet) {
						logger.info("------------RunningPlugin--SoftwareFacet");
						SoftwareFacet sf = (SoftwareFacet) f;
						if (!list.contains(sf.getGroup()))
							list.add(sf.getGroup());
					}
					break;	

				case "HostingNode":
					if (f instanceof NetworkingFacet) {
						logger.info("------------HostingNode--Networking");
						NetworkingFacet nf = (NetworkingFacet) f;
						if (!list.contains(nf.getDomainName())) {
							list.add(nf.getDomainName());
						}
					}
					break;

				
				case "VirtualService":
					if (f instanceof SoftwareFacet) {
						logger.info("------------VirtualService--SoftwareFacet");
						SoftwareFacet sf = (SoftwareFacet) f;
						if (!list.contains(sf.getGroup()))
							list.add(sf.getGroup());
					}
					break;
				case "Site":
					if (f instanceof IdentifierFacet) {
						logger.info("------------Site--IdentifierFacet");
						IdentifierFacet sf = (IdentifierFacet) f;
						if (!list.contains(sf.getIdentificationType().toString()))
							list.add(sf.getIdentificationType().toString());
					}
					break;
				
				case "Software":
					if (f instanceof SoftwareFacet) {
						logger.info("------------Software--SoftwareFacet");
						SoftwareFacet sf = (SoftwareFacet) f;
						if (!list.contains(sf.getGroup()))
							list.add(sf.getGroup());
					}
					break;	

				case "Plugin":
					if (f instanceof SoftwareFacet) {
						logger.info("------------Plugin--SoftwareFacet");
						SoftwareFacet sf = (SoftwareFacet) f;
						if (!list.contains(sf.getGroup()))
							list.add(sf.getGroup());
					}
					break;	

				}

			}
		}
		return list;

	}
	
	
    //TODO
	public static ArrayList<String> getSubResourcesTreeQuery(ResourceRegistryClient resourceRegistryClient,
			String entity) throws Exception {

		ArrayList<String> list = new ArrayList<>();
		String field = null;
		String identifiedFacet = null;
		switch (entity) {

		case "Actor":
			field = "eMail";
			identifiedFacet = "ContactFacet";
			break;
		case "LegalBody":
			field = "eMail";
			identifiedFacet = "ContactFacet";
			break;
		case "Person":
			field = "eMail";
			identifiedFacet = "ContactFacet";
			break;
		case "ConfigurationTemplate":
			field = "type";
			identifiedFacet = "IdentifierFacet";
			break;
		case "Configuration":
			field = "type";
			identifiedFacet = "IdentifierFacet";
			break;
		case "Dataset":
			field = "type";
			identifiedFacet = "IdentifierFacet";
			break;
		case "ConcreteDataset":
			field = "type";
			identifiedFacet = "IdentifierFacet";
			break;
		case "Schema":
			field = "name";
			identifiedFacet = "SchemaFacet";
			break;
		case "EService": // GcoreEndPoint
			field = "group";
			identifiedFacet = "SoftwareFacet";
			break;
		case "RunningPlugin":
			field = "group";
			identifiedFacet = "SoftwareFacet";
			break;
		case "HostingNode":
			field = "domainName";
			identifiedFacet = "NetworkingFacet";
			break;
		case "VirtualService": // Service
			field = "group";
			identifiedFacet = "SoftwareFacet";
			break;
		case "Site":
			field = "type";
			identifiedFacet = "IdentifierFacet";
			break;
		case "Software":
			field = "group";
			identifiedFacet = "SoftwareFacet";
			break;
		case "Plugin":
			field = "group";
			identifiedFacet = "SoftwareFacet";
			break;
		
			
		default:
			return new ArrayList<>(0);

		}

		try {
			String query = "SELECT DISTINCT(" + field + ") AS " + field + " "
					+ "FROM (TRAVERSE outE('IsIdentifiedBy'),inV('" + identifiedFacet + "') FROM " + entity + ")";

			logger.info("------------query----------->" + query);

			String result = resourceRegistryClient.rawQuery(query, true);

			if (result != null && !result.isEmpty()) {
				logger.info("--------result-------->" + result);
				JSONArray jsonArray = new JSONArray(result);
				for (int i = 0; i < jsonArray.length(); i++) {
					list.add(jsonArray.getJSONObject(i).get(field).toString());
				}
			} else {
				logger.info("--------result-------->Attention invalid result!");
			}
		} catch (Exception e) {
			logger.error(e.getLocalizedMessage(), e);
		}
		return list;

	}

	

	///TODO
	
	public static List<String> createListActor(ResourceRegistryClient resourceRegistryClient, String typeC,
			String subTypeC) throws Exception {
		JAXBContext context = JAXBContext.newInstance(GenericResourceObject.class);
		Marshaller m = context.createMarshaller();
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		m.setProperty(Marshaller.JAXB_FRAGMENT, true);

		List<String> resource = new ArrayList<String>();
		String id = "";
		String type = "Actor";
		String subType = "";
		String serviceClass = "";
		String serviceName = "";
		// String version = "";

		List<Actor> actors = (List<Actor>) resourceRegistryClient.getInstances(Actor.class, false);
		if (actors != null) {
			logger.info("Actors found: {}", actors.size());
		} else {
			logger.info("Actors not found");
			return resource;
		}
		for (Actor actor : actors) {

			id = actor.getID().toString();

			List<? extends Facet> facets = actor.getIdentificationFacets();
			for (Facet f : facets) {
				if (f instanceof ContactFacet) {
					ContactFacet sf = (ContactFacet) f;
					// version = sf.getVersion();

					serviceName = sf.getName();
					serviceClass = sf.getSurname();
					subType = "";
				}
			}
			CacheList.resourceid.put(id, new ResourceObject(serviceName, actor.toString()));

			GenericResourceObject temp = new GenericResourceObject(id, type, subType, serviceName, serviceClass,
					ScopeProvider.instance.get());

			StringWriter sw = new StringWriter();
			m.marshal(temp, sw);

			if (subTypeC != null) {
				if (subType.equals(subTypeC)) {
					resource.add(sw.toString());
				}
			} else
				resource.add(sw.toString());

		}
		logger.info("Actor: {}", resource);
		return resource;
	}
	
	public static List<String> createListLegalBody(ResourceRegistryClient resourceRegistryClient, String typeC,
			String subTypeC) throws Exception {
		JAXBContext context = JAXBContext.newInstance(GenericResourceObject.class);
		Marshaller m = context.createMarshaller();
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		m.setProperty(Marshaller.JAXB_FRAGMENT, true);

		List<String> resource = new ArrayList<String>();
		String id = "";
		String type = "LegalBody";
		String subType = "";
		String serviceClass = "";
		String serviceName = "";
		// String version = "";

		List<LegalBody> legalBodys = (List<LegalBody>) resourceRegistryClient.getInstances(LegalBody.class, false);
		if (legalBodys != null) {
			logger.info("LegalBodys found: {}", legalBodys.size());
		} else {
			logger.info("LegalBodys not found");
			return resource;
		}
		for (LegalBody actor : legalBodys) {

			id = actor.getID().toString();

			List<? extends Facet> facets = actor.getIdentificationFacets();
			for (Facet f : facets) {
				if (f instanceof ContactFacet) {
					ContactFacet sf = (ContactFacet) f;
					// version = sf.getVersion();

					serviceName = sf.getName();
					serviceClass = sf.getSurname();
					subType = "";
				}
			}
			CacheList.resourceid.put(id, new ResourceObject(serviceName, actor.toString()));

			GenericResourceObject temp = new GenericResourceObject(id, type, subType, serviceName, serviceClass,
					ScopeProvider.instance.get());

			StringWriter sw = new StringWriter();
			m.marshal(temp, sw);

			if (subTypeC != null) {
				if (subType.equals(subTypeC)) {
					resource.add(sw.toString());
				}
			} else
				resource.add(sw.toString());

		}
		logger.info("LegalBody: {}", resource);
		return resource;
	}
	
	public static List<String> createListPerson(ResourceRegistryClient resourceRegistryClient, String typeC,
			String subTypeC) throws Exception {
		JAXBContext context = JAXBContext.newInstance(GenericResourceObject.class);
		Marshaller m = context.createMarshaller();
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		m.setProperty(Marshaller.JAXB_FRAGMENT, true);

		List<String> resource = new ArrayList<String>();
		String id = "";
		String type = "Person";
		String subType = "";
		String serviceClass = "";
		String serviceName = "";
		// String version = "";

		List<Person> persons = (List<Person>) resourceRegistryClient.getInstances(Person.class, false);
		if (persons != null) {
			logger.info("Persons found: {}", persons.size());
		} else {
			logger.info("Persons not found");
			return resource;
		}
		for (Person person : persons) {

			id = person.getID().toString();

			List<? extends Facet> facets = person.getIdentificationFacets();
			for (Facet f : facets) {
				if (f instanceof ContactFacet) {
					ContactFacet sf = (ContactFacet) f;
					// version = sf.getVersion();

					serviceName = sf.getName();
					serviceClass = sf.getSurname();
					subType = "";
				}
			}
			CacheList.resourceid.put(id, new ResourceObject(serviceName, person.toString()));

			GenericResourceObject temp = new GenericResourceObject(id, type, subType, serviceName, serviceClass,
					ScopeProvider.instance.get());

			StringWriter sw = new StringWriter();
			m.marshal(temp, sw);

			if (subTypeC != null) {
				if (subType.equals(subTypeC)) {
					resource.add(sw.toString());
				}
			} else
				resource.add(sw.toString());

		}
		logger.info("Person: {}", resource);
		return resource;
	}
	
	/***
	 * Create a list for configuration (aka GenericResourceObject)
	 * 
	 * @param scope
	 * @param typeE
	 * @return
	 * @throws Exception
	 */
	public static List<String> createListConfigurationTemplate(ResourceRegistryClient resourceRegistryClient, String typeC,
			String subTypeC) throws Exception {

		JAXBContext context = JAXBContext.newInstance(GenericResourceObject.class);
		Marshaller m = context.createMarshaller();
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		m.setProperty(Marshaller.JAXB_FRAGMENT, true);

		List<String> resource = new ArrayList<String>();
		String id = "";
		String type = "ConfigurationTemplate";
		String subType = "";
		String name = "";
		String description = "";
		List<ConfigurationTemplate> configurationTemplates = (List<ConfigurationTemplate>) resourceRegistryClient
				.getInstances(ConfigurationTemplate.class, true);
		if (configurationTemplates != null) {
			logger.info("ConfigurationTemplate found: {}", configurationTemplates.size());
		} else {
			logger.info("ConfigurationTemplate not found!");
			return resource;
		}
		
		for (ConfigurationTemplate configurationTemplate : configurationTemplates) {
			id = configurationTemplate.getID().toString();
			List<? extends Facet> facets = configurationTemplate.getIdentificationFacets();
			for (Facet f : facets) {
				if (f instanceof IdentifierFacet) {
					IdentifierFacet sf = (IdentifierFacet) f;
					name = sf.getValue();
					description = sf.getIdentificationType().toString();
					subType = sf.getIdentificationType().toString();
					
				}
			}

			CacheList.resourceid.put(id, new ResourceObject(name, configurationTemplate.toString()));
			GenericResourceObject temp = new GenericResourceObject(id, type, subType, name, description,
					ScopeProvider.instance.get());

			StringWriter sw = new StringWriter();
			m.marshal(temp, sw);
			// filter to subtype
			if (subTypeC != null) {
				if (subType.equals(subTypeC)) {
					resource.add(sw.toString());
				}
			} else
				resource.add(sw.toString());

		}
		logger.info("ConfigurationTemplate: {}", resource);
		return resource;

	}
	
	/***
	 * Create a list for configuration (aka GenericResourceObject)
	 * 
	 * @param scope
	 * @param typeE
	 * @return
	 * @throws Exception
	 */
	public static List<String> createListConfiguration(ResourceRegistryClient resourceRegistryClient, String typeC,
			String subTypeC) throws Exception {

		JAXBContext context = JAXBContext.newInstance(GenericResourceObject.class);
		Marshaller m = context.createMarshaller();
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		m.setProperty(Marshaller.JAXB_FRAGMENT, true);

		List<String> resource = new ArrayList<String>();
		String id = "";
		// String type="EService";
		String type = "GenericResource";
		String subType = "";
		String name = "";
		String description = "";
		List<Configuration> configurations = (List<Configuration>) resourceRegistryClient
				.getInstances(Configuration.class, false);
		if (configurations != null) {
			logger.info("Configurations found: {}", configurations.size());
		} else {
			logger.info("Configurations not found!");
			return resource;
		}
		for (Configuration configuration : configurations) {
			id = configuration.getID().toString();
			List<? extends Facet> facets = configuration.getIdentificationFacets();
			for (Facet f : facets) {
				if (f instanceof IdentifierFacet) {
					IdentifierFacet sf = (IdentifierFacet) f;
					name = sf.getValue();
					subType = sf.getIdentificationType().toString();
					description = sf.getIdentificationType().toString();

				}
			}

			CacheList.resourceid.put(id, new ResourceObject(name, configuration.toString()));
			GenericResourceObject temp = new GenericResourceObject(id, type, subType, name, description,
					ScopeProvider.instance.get());

			StringWriter sw = new StringWriter();
			m.marshal(temp, sw);
			// filter to subtype
			if (subTypeC != null) {
				if (subType.equals(subTypeC)) {
					resource.add(sw.toString());
				}
			} else
				resource.add(sw.toString());

		}
		logger.info("Configuration: {}", resource);
		return resource;

	}
	
	public static List<String> createListDataset(ResourceRegistryClient resourceRegistryClient, String typeC,
			String subTypeC) throws Exception {
		JAXBContext context = JAXBContext.newInstance(GenericResourceObject.class);
		Marshaller m = context.createMarshaller();
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		m.setProperty(Marshaller.JAXB_FRAGMENT, true);

		List<String> resource = new ArrayList<String>();
		String id = "";
		String type = "Dataset";
		String subType = "";
		String serviceClass = "";
		String serviceName = "";
		// String version = "";

		List<Dataset> datasets = (List<Dataset>) resourceRegistryClient.getInstances(Dataset.class, false);
		if (datasets != null) {
			logger.info("Datasets found: {}", datasets.size());
		} else {
			logger.info("Datasets not found!");
			return resource;
		}
		for (Dataset dataset : datasets) {

			id = dataset.getID().toString();

			List<? extends Facet> facets = dataset.getIdentificationFacets();
			for (Facet f : facets) {
				if (f instanceof IdentifierFacet) {
					IdentifierFacet sf = (IdentifierFacet) f;
					// version = sf.getVersion();

					serviceName = sf.getValue();
					serviceClass = sf.getIdentificationType().toString();
					subType = sf.getIdentificationType().toString();
				}
			}
			CacheList.resourceid.put(id, new ResourceObject(serviceName, dataset.toString()));

			GenericResourceObject temp = new GenericResourceObject(id, type, subType, serviceName, serviceClass,
					ScopeProvider.instance.get());

			StringWriter sw = new StringWriter();
			m.marshal(temp, sw);

			if (subTypeC != null) {
				if (subType.equals(subTypeC)) {
					resource.add(sw.toString());
				}
			} else
				resource.add(sw.toString());

		}
		logger.info("Dataset: {}", resource);
		return resource;
	}
	
	public static List<String> createListConcreteDataset(ResourceRegistryClient resourceRegistryClient, String typeC,
			String subTypeC) throws Exception {
		JAXBContext context = JAXBContext.newInstance(GenericResourceObject.class);
		Marshaller m = context.createMarshaller();
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		m.setProperty(Marshaller.JAXB_FRAGMENT, true);

		List<String> resource = new ArrayList<String>();
		String id = "";
		String type = "ConcreteDataset";
		String subType = "";
		String serviceClass = "";
		String serviceName = "";
		// String version = "";

		List<ConcreteDataset> concretedatasets = (List<ConcreteDataset>) resourceRegistryClient.getInstances(ConcreteDataset.class, false);
		if (concretedatasets != null) {
			logger.info("ConcreteDatasets found: {}", concretedatasets.size());
		} else {
			logger.info("ConcreteDatasets not found!");
			return resource;
		}
		for (ConcreteDataset concreteDataset : concretedatasets) {

			id = concreteDataset.getID().toString();

			List<? extends Facet> facets = concreteDataset.getIdentificationFacets();
			for (Facet f : facets) {
				if (f instanceof IdentifierFacet) {
					IdentifierFacet sf = (IdentifierFacet) f;
					// version = sf.getVersion();

					serviceName = sf.getValue();
					serviceClass = sf.getIdentificationType().toString();
					subType = sf.getIdentificationType().toString();
				}
			}
			CacheList.resourceid.put(id, new ResourceObject(serviceName, concreteDataset.toString()));

			GenericResourceObject temp = new GenericResourceObject(id, type, subType, serviceName, serviceClass,
					ScopeProvider.instance.get());

			StringWriter sw = new StringWriter();
			m.marshal(temp, sw);

			if (subTypeC != null) {
				if (subType.equals(subTypeC)) {
					resource.add(sw.toString());
				}
			} else
				resource.add(sw.toString());

		}
		logger.info("ConcreteDataset: {}", resource);
		return resource;
	}
	
	
	public static List<String> createListSchema(ResourceRegistryClient resourceRegistryClient, String typeC,
			String subTypeC) throws Exception {
		JAXBContext context = JAXBContext.newInstance(GenericResourceObject.class);
		Marshaller m = context.createMarshaller();
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		m.setProperty(Marshaller.JAXB_FRAGMENT, true);

		List<String> resource = new ArrayList<String>();
		String id = "";
		String type = "Schema";
		String subType = "";
		String serviceClass = "";
		String serviceName = "";
		// String version = "";

		List<Schema> schemas = (List<Schema>) resourceRegistryClient.getInstances(Schema.class, false);
		if (schemas != null) {
			logger.info("Schemas found: {}", schemas.size());
		} else {
			logger.info("Schemas not found!");
			return resource;
		}
		for (Schema schema : schemas) {

			id = schema.getID().toString();

			List<? extends Facet> facets = schema.getIdentificationFacets();
			for (Facet f : facets) {
				if (f instanceof SchemaFacet) {
					SchemaFacet sf = (SchemaFacet) f;
					// version = sf.getVersion();

					serviceName = sf.getName();
					serviceClass = sf.getDescription();
					subType = sf.getSchema().getValue();
				}
			}
			CacheList.resourceid.put(id, new ResourceObject(serviceName, schema.toString()));

			GenericResourceObject temp = new GenericResourceObject(id, type, subType, serviceName, serviceClass,
					ScopeProvider.instance.get());

			StringWriter sw = new StringWriter();
			m.marshal(temp, sw);

			if (subTypeC != null) {
				if (subType.equals(subTypeC)) {
					resource.add(sw.toString());
				}
			} else
				resource.add(sw.toString());

		}
		logger.info("Schema: {}", resource);
		return resource;
	}
	
	
	/***
	 * Create a list for eservice (aka gcore endpoint)
	 * 
	 * @param scope
	 * @param typeE
	 * @return
	 * @throws Exception
	 */
	public static List<String> createListEservice(ResourceRegistryClient resourceRegistryClient, String typeC,
			String subTypeC) throws Exception {
		JAXBContext context = JAXBContext.newInstance(GcoreEndPointObject.class);
		Marshaller m = context.createMarshaller();
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		m.setProperty(Marshaller.JAXB_FRAGMENT, true);

		List<String> resource = new ArrayList<String>();
		String id = "";
		String type = "EService";
		// String type="RunningInstance";
		String subType = "";
		String serviceClass = "";
		String serviceName = "";
		String version = "";
		String status = "";
		String ghnName = "";

		List<EService> eservices = (List<EService>) resourceRegistryClient.getInstances(EService.class, false);
		for (EService et : eservices) {
			id = et.getID().toString();
			List<? extends Facet> facets = et.getIdentificationFacets();
			for (Facet f : facets) {
				if (f instanceof SoftwareFacet) {
					SoftwareFacet sf = (SoftwareFacet) f;
					version = sf.getVersion();
					serviceName = sf.getName();
					serviceClass = sf.getGroup();
					subType = sf.getGroup();
					version = sf.getVersion();
				}
			}
			CacheList.resourceid.put(id, new ResourceObject(serviceName, et.toString()));

			ghnName = "";
			status = "";
			List<ConsistsOf<? extends Resource, ? extends Facet>> consist = et.getConsistsOf();
			for (ConsistsOf<? extends Resource, ? extends Facet> c : consist) {
				if (c instanceof ConsistsOf) {
					if (c.getTarget() instanceof AccessPointFacet) {
						AccessPointFacet af = (AccessPointFacet) c.getTarget();
						try {
							ghnName = af.getEndpoint().getHost().toString();
						} catch (Exception e) {
							ghnName = "";
						}
					}
					if (c.getTarget() instanceof StateFacet) {
						StateFacet stf = (StateFacet) c.getTarget();
						try {
							status = stf.getValue().toLowerCase();
						} catch (Exception e) {
							status = "";
						}
					}
				}
			}
			GcoreEndPointObject temp = new GcoreEndPointObject(id, type, subType, ScopeProvider.instance.get(),
					serviceClass, serviceName, version, status, ghnName);
			StringWriter sw = new StringWriter();
			m.marshal(temp, sw);

			if (subTypeC != null) {
				if (subType.equals(subTypeC)) {
					resource.add(sw.toString());
				}
			} else
				resource.add(sw.toString());

		}
		logger.info("EService: {}", resource);
		return resource;
	}
	
	public static List<String> createListRunningPlugin(ResourceRegistryClient resourceRegistryClient, String typeC,
			String subTypeC) throws Exception {
		JAXBContext context = JAXBContext.newInstance(GenericResourceObject.class);
		Marshaller m = context.createMarshaller();
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		m.setProperty(Marshaller.JAXB_FRAGMENT, true);

		List<String> resource = new ArrayList<String>();
		String id = "";
		String type = "RunningPlugin";
		String subType = "";
		String serviceClass = "";
		String serviceName = "";
		// String version = "";

		List<RunningPlugin> runningPlugins = (List<RunningPlugin>) resourceRegistryClient.getInstances(RunningPlugin.class, false);
		if (runningPlugins != null) {
			logger.info("RunningPlugins found: {}", runningPlugins.size());
		} else {
			logger.info("RunningPlugins not found");
			return resource;
		}
		for (RunningPlugin runningPlugin : runningPlugins) {

			id = runningPlugin.getID().toString();

			List<? extends Facet> facets = runningPlugin.getIdentificationFacets();
			for (Facet f : facets) {
				if (f instanceof SoftwareFacet) {
					SoftwareFacet sf = (SoftwareFacet) f;
					// version = sf.getVersion();

					serviceName = sf.getName();
					serviceClass = sf.getGroup();
					subType = sf.getGroup();
				}
			}
			CacheList.resourceid.put(id, new ResourceObject(serviceName, runningPlugin.toString()));

			GenericResourceObject temp = new GenericResourceObject(id, type, subType, serviceName, serviceClass,
					ScopeProvider.instance.get());

			StringWriter sw = new StringWriter();
			m.marshal(temp, sw);

			if (subTypeC != null) {
				if (subType.equals(subTypeC)) {
					resource.add(sw.toString());
				}
			} else
				resource.add(sw.toString());

		}
		logger.info("RunningPlugin: {}", resource);
		return resource;
	}

	/***
	 * Create a list for hosting node (aka GHN)
	 * 
	 * @param scope
	 * @param typeE
	 * @return
	 * @throws Exception
	 * @throws Exception
	 */
	public static List<String> createListHostingNode(ResourceRegistryClient resourceRegistryClient, String typeC,
			String subTypeC) throws Exception {

		JAXBContext context = JAXBContext.newInstance(HostingNodeObject.class);
		Marshaller m = context.createMarshaller();
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		m.setProperty(Marshaller.JAXB_FRAGMENT, true);

		List<String> resource = new ArrayList<String>();
		String id = "";
		// String type="HostingNode";
		String type = "GHN";
		String subType = "";// --
		String status = "";// ---
		String name = "";//
		String upTime = "-";
		String lastUpdate = "-";
		long localAvailableSpace = 0;
		long virtualSize = 0;
		long virtualAvailable = 0;
		String loadLast1Min = "-";
		String loadLast5Min = "-";
		String loadLast15Min = "-";
		String gcfVersion = "";
		String ghnVersion = "";

		resourceRegistryClient.setIncludeMeta(true);
		List<HostingNode> ehosting = (List<HostingNode>) resourceRegistryClient.getInstances(HostingNode.class, false);
		for (HostingNode eh : ehosting) {
			id = eh.getID().toString();
			lastUpdate = eh.getMetadata().getLastUpdateTime().toString();
			List<? extends Facet> facets = eh.getIdentificationFacets();
			for (Facet f : facets) {
				if (f instanceof NetworkingFacet) {
					NetworkingFacet nf = (NetworkingFacet) f;
					subType = nf.getDomainName();
					name = nf.getHostName();
				}
			}

			CacheList.resourceid.put(id, new ResourceObject(name, eh.toString()));
			List<ConsistsOf<? extends Resource, ? extends Facet>> consist = eh.getConsistsOf();
			for (ConsistsOf<? extends Resource, ? extends Facet> c : consist) {
				// logger.info("------------ConsistsOf--ConsistsOf--
				// c"+c.toString());
				if (c instanceof ConsistsOf) {

					if (c.getTarget() instanceof SimplePropertyFacet) {
						SimplePropertyFacet sp = (SimplePropertyFacet) c.getTarget();
						try {
							gcfVersion = sp.getAdditionalProperty("SmartGearsDistribution").toString();
							ghnVersion = sp.getAdditionalProperty("SmartGears").toString();
						} catch (Exception e) {
							gcfVersion = "";
							ghnVersion = "";
						}
					}
					// get disk space
					if (c instanceof HasPersistentMemory) {
						HasPersistentMemory hpm = (HasPersistentMemory) c;
						try {
							MemoryFacet mfh = (MemoryFacet) hpm.getTarget();
							localAvailableSpace = mfh.getSize() - mfh.getUsed();
						} catch (Exception e) {
							localAvailableSpace = 0;
						}
					}
					// get ram space
					if (c instanceof HasVolatileMemory) {
						HasVolatileMemory hvm = (HasVolatileMemory) c;
						try {
							if (hvm.getAdditionalProperty("memoryType").equals("RAM")) {
								MemoryFacet mf = (MemoryFacet) hvm.getTarget();
								virtualAvailable = mf.getSize() - mf.getUsed();
								virtualSize = mf.getSize();
							}
						} catch (Exception e) {
							virtualAvailable = 0;
							virtualSize = 0;
						}
					}
					// get status
					if (c.getTarget() instanceof StateFacet) {
						StateFacet st = (StateFacet) c.getTarget();
						try {
							status = st.getValue();
						} catch (Exception e) {
							status = "";
						}
					}
				}
			}
			HostingNodeObject temp = new HostingNodeObject(id, type, subType, status, name, upTime, lastUpdate,
					localAvailableSpace, virtualSize, virtualAvailable, loadLast1Min, loadLast5Min, loadLast15Min,
					gcfVersion, ghnVersion, ScopeProvider.instance.get());

			StringWriter sw = new StringWriter();
			m.marshal(temp, sw);
			// filter to subtype
			if (subTypeC != null) {
				if (subType.equals(subTypeC)) {
					resource.add(sw.toString());
				}
			} else
				resource.add(sw.toString());

		}
		return resource;
	}
	
	
	public static List<String> createListVirtualService(ResourceRegistryClient resourceRegistryClient, String typeC,
			String subTypeC) throws Exception {
		JAXBContext context = JAXBContext.newInstance(GenericResourceObject.class);
		Marshaller m = context.createMarshaller();
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		m.setProperty(Marshaller.JAXB_FRAGMENT, true);

		List<String> resource = new ArrayList<String>();
		String id = "";
		String type = "VirtualService";
		String subType = "";
		String serviceClass = "";
		String serviceName = "";
		// String version = "";

		List<VirtualService> virtualServices = (List<VirtualService>) resourceRegistryClient
				.getInstances(VirtualService.class, false);
		if (virtualServices != null) {
			logger.info("VirtualServices found: {}", virtualServices.size());
		} else {
			logger.info("VirtualServices not found");
			return resource;
		}
		for (VirtualService vs : virtualServices) {
			id = vs.getID().toString();

			List<? extends Facet> facets = vs.getIdentificationFacets();
			for (Facet f : facets) {
				if (f instanceof SoftwareFacet) {
					SoftwareFacet sf = (SoftwareFacet) f;
					// version = sf.getVersion();

					serviceName = sf.getName();
					serviceClass = sf.getGroup();
					subType = sf.getGroup();
				}
			}
			CacheList.resourceid.put(id, new ResourceObject(serviceName, vs.toString()));

			GenericResourceObject temp = new GenericResourceObject(id, type, subType, serviceName, serviceClass,
					ScopeProvider.instance.get());

			StringWriter sw = new StringWriter();
			m.marshal(temp, sw);

			if (subTypeC != null) {
				if (subType.equals(subTypeC)) {
					resource.add(sw.toString());
				}
			} else
				resource.add(sw.toString());

		}
		logger.info("VirtualService: {}", resource);
		return resource;
	}

	public static List<String> createListSite(ResourceRegistryClient resourceRegistryClient, String typeC,
			String subTypeC) throws Exception {
		JAXBContext context = JAXBContext.newInstance(GenericResourceObject.class);
		Marshaller m = context.createMarshaller();
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		m.setProperty(Marshaller.JAXB_FRAGMENT, true);

		List<String> resource = new ArrayList<String>();
		String id = "";
		String type = "Site";
		String subType = "";
		String serviceClass = "";
		String serviceName = "";
		// String version = "";

		List<Site> sites = (List<Site>) resourceRegistryClient.getInstances(Site.class, false);
		if (sites != null) {
			logger.info("Site found: {}", sites.size());
		} else {
			logger.info("Site not found");
			return resource;
		}
		for (Site site : sites) {

			id = site.getID().toString();

			List<? extends Facet> facets = site.getIdentificationFacets();
			for (Facet f : facets) {
				if (f instanceof IdentifierFacet) {
					IdentifierFacet sf = (IdentifierFacet) f;
					// version = sf.getVersion();

					serviceName = sf.getValue();
					serviceClass = sf.getIdentificationType().toString();
					subType = sf.getIdentificationType().toString();
				}
			}
			CacheList.resourceid.put(id, new ResourceObject(serviceName, site.toString()));

			GenericResourceObject temp = new GenericResourceObject(id, type, subType, serviceName, serviceClass,
					ScopeProvider.instance.get());

			StringWriter sw = new StringWriter();
			m.marshal(temp, sw);

			if (subTypeC != null) {
				if (subType.equals(subTypeC)) {
					resource.add(sw.toString());
				}
			} else
				resource.add(sw.toString());

		}
		logger.info("Site: {}", resource);
		return resource;
	}
	
	
	public static List<String> createListSoftware(ResourceRegistryClient resourceRegistryClient, String typeC,
			String subTypeC) throws Exception {
		JAXBContext context = JAXBContext.newInstance(GenericResourceObject.class);
		Marshaller m = context.createMarshaller();
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		m.setProperty(Marshaller.JAXB_FRAGMENT, true);

		List<String> resource = new ArrayList<String>();
		String id = "";
		String type = "Software";
		String subType = "";
		String serviceClass = "";
		String serviceName = "";
		// String version = "";

		List<Software> softwares = (List<Software>) resourceRegistryClient.getInstances(Software.class, false);
		if (softwares != null) {
			logger.info("Softwares found: {}", softwares.size());
		} else {
			logger.info("Softwares not found");
			return resource;
		}
		for (Software software : softwares) {

			id = software.getID().toString();

			List<? extends Facet> facets = software.getIdentificationFacets();
			for (Facet f : facets) {
				if (f instanceof SoftwareFacet) {
					SoftwareFacet sf = (SoftwareFacet) f;
					// version = sf.getVersion();

					serviceName = sf.getName();
					serviceClass = sf.getGroup();
					subType = sf.getGroup();
				}
			}
			CacheList.resourceid.put(id, new ResourceObject(serviceName, software.toString()));

			GenericResourceObject temp = new GenericResourceObject(id, type, subType, serviceName, serviceClass,
					ScopeProvider.instance.get());

			StringWriter sw = new StringWriter();
			m.marshal(temp, sw);

			if (subTypeC != null) {
				if (subType.equals(subTypeC)) {
					resource.add(sw.toString());
				}
			} else
				resource.add(sw.toString());

		}
		logger.info("Software: {}", resource);
		return resource;
	}
	
	public static List<String> createListPlugin(ResourceRegistryClient resourceRegistryClient, String typeC,
			String subTypeC) throws Exception {
		JAXBContext context = JAXBContext.newInstance(GenericResourceObject.class);
		Marshaller m = context.createMarshaller();
		m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
		m.setProperty(Marshaller.JAXB_FRAGMENT, true);

		List<String> resource = new ArrayList<String>();
		String id = "";
		String type = "Plugin";
		String subType = "";
		String serviceClass = "";
		String serviceName = "";
		// String version = "";

		List<Plugin> plugins = (List<Plugin>) resourceRegistryClient.getInstances(Plugin.class, false);
		if (plugins != null) {
			logger.info("Plugins found: {}", plugins.size());
		} else {
			logger.info("Plugins not found");
			return resource;
		}
		for (Plugin plugin : plugins) {

			id = plugin.getID().toString();

			List<? extends Facet> facets = plugin.getIdentificationFacets();
			for (Facet f : facets) {
				if (f instanceof SoftwareFacet) {
					SoftwareFacet sf = (SoftwareFacet) f;
					// version = sf.getVersion();

					serviceName = sf.getName();
					serviceClass = sf.getGroup();
					subType = sf.getGroup();
				}
			}
			CacheList.resourceid.put(id, new ResourceObject(serviceName, plugin.toString()));

			GenericResourceObject temp = new GenericResourceObject(id, type, subType, serviceName, serviceClass,
					ScopeProvider.instance.get());

			StringWriter sw = new StringWriter();
			m.marshal(temp, sw);

			if (subTypeC != null) {
				if (subType.equals(subTypeC)) {
					resource.add(sw.toString());
				}
			} else
				resource.add(sw.toString());

		}
		logger.info("Plugin: {}", resource);
		return resource;
	}

}
