package eu.dnetlib.enabling.ui.server;

import java.io.InputStream;
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Required;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.tools.ServiceLocator;
import eu.dnetlib.enabling.ui.common.beans.AggregatorInfo;
import eu.dnetlib.enabling.ui.common.beans.AllDSInfo;
import eu.dnetlib.enabling.ui.common.beans.BlackBoardInfo;
import eu.dnetlib.enabling.ui.common.beans.DHNInfo;
import eu.dnetlib.enabling.ui.common.beans.IndexInfo;
import eu.dnetlib.enabling.ui.common.beans.MDStoreInfo;
import eu.dnetlib.enabling.ui.common.beans.RepositoryDetailsInfo;
import eu.dnetlib.enabling.ui.common.beans.RepositoryStatusInfo;
import eu.dnetlib.enabling.ui.common.beans.ServiceInfo;
import eu.dnetlib.enabling.ui.common.services.LookupService;
import eu.dnetlib.enabling.ui.common.services.MyGwtException;


public class LookupServlet extends RemoteServiceServlet implements LookupService {
	private static final long serialVersionUID = 228602254444074392L;
	private ServiceLocator<ISLookUpService> isLookUpLocator;
	private String smokepingBaseUrl;
	private String muninBaseUrl;


	private static final Log log = LogFactory.getLog(LookupServlet.class); // NOPMD by marko on 11/24/08 5:02 PM

	public LookupServlet() {
		super();
	}

	public ServiceLocator<ISLookUpService> getIsLookUpLocator() {
		return isLookUpLocator;
	}

	@Required
	public void setIsLookUpLocator(ServiceLocator<ISLookUpService> isLookUpLocator) {
		this.isLookUpLocator = isLookUpLocator;
	}

	public String getSmokepingBaseUrl() {
		return smokepingBaseUrl;
	}

	@Required
	public void setSmokepingBaseUrl(String smokepingBaseUrl) {
		this.smokepingBaseUrl = smokepingBaseUrl;
	}

	public String getMuninBaseUrl() {
		return muninBaseUrl;
	}

	@Required
	public void setMuninBaseUrl(String muninBaseUrl) {
		this.muninBaseUrl = muninBaseUrl;
	}


	public List<String> executeQuery(String query) {
		List<String> res = null;
		try {
			res = isLookUpLocator.getService().quickSearchProfile(query);
		} catch (Exception e) {
			return new ArrayList<String>();
		}
		if (res == null) return new ArrayList<String>();
		return res;
	}



	public List<ServiceInfo> listServices() {
		return _listServices(null);
	}


	private List<ServiceInfo> _listServices(String DHNid) {
		String query = "";
		if ((DHNid == null)||(DHNid.isEmpty())) {
			query = "for $x in collection('/db/DRIVER/ServiceResources/') " +
			"order by $x/RESOURCE_PROFILE/HEADER/RESOURCE_TYPE/@value " +
			"return $x";
		} else {
			query = "for $x in collection('/db/DRIVER/ServiceResources') " +
			"where $x//PARENT_ID/@value/string()='" + DHNid + "' "+
			"return $x";
		}

		List<String> elems = executeQuery(query);
		List<ServiceInfo> ret = new ArrayList<ServiceInfo>();
		SAXReader xmlParser = new SAXReader();

		for (String xml : elems) {
			try {
				Document doc = xmlParser.read(new StringReader(xml));
				ServiceInfo row = new ServiceInfo();
				row.setId(doc.selectSingleNode("//RESOURCE_IDENTIFIER/@value").getText());
				row.setType(doc.selectSingleNode("//RESOURCE_TYPE/@value").getText());
				row.setDate(doc.selectSingleNode("//DATE_OF_CREATION/@value").getText());
				row.setUri(doc.selectSingleNode("//RESOURCE_URI/@value").getText());
				ret.add(row);
			} catch (DocumentException e) {

			}
		}
		return ret;


	}


	public List<String> listSchemas() {
		try {
			List<String> list = isLookUpLocator.getService().listResourceTypes();
			Collections.sort(list);
			return list;
		} catch (Exception e) {
			return new ArrayList<String>();
		}
	}




	public List<DHNInfo> listDHNs() {
		String query = "for $x in collection('/db/DRIVER/ServiceResources/HostingNodeManagerServiceResourceType') return $x";

		SAXReader reader = new SAXReader();

		List<DHNInfo> res = new ArrayList<DHNInfo>();
		for (String s: executeQuery(query)) {
			Document doc;
			try {

				doc = reader.read(new StringReader(s));

				String id = doc.valueOf("//RESOURCE_IDENTIFIER/@value");

				String addr;
				int port;
				try {
					URL url = new URL(doc.valueOf("//RESOURCE_URI/@value"));
					addr = url.getHost();
					port = url.getPort();
				} catch (MalformedURLException e) {
					addr = "0.0.0.0";
					port = 80;
				}

				DHNInfo dhn = new DHNInfo();
				dhn.setIdentifier(id);
				dhn.setAddress(addr + ":" + port);
				dhn.setName(doc.valueOf("//PROPERTY[@key='name']/@value"));
				dhn.setLat     (Float.parseFloat(doc.valueOf("//PROPERTY[@key='latitude']/@value")));
				dhn.setLng     (Float.parseFloat(doc.valueOf("//PROPERTY[@key='longitude']/@value")));
				dhn.setTimezone(Float.parseFloat(doc.valueOf("//PROPERTY[@key='timezone']/@value")));
				dhn.setMuninUrl(muninBaseUrl + addr);
				dhn.setSmokepingUrl(smokepingBaseUrl + addr);
				dhn.setServices(_listServices(id));
				res.add(dhn);
			} catch (DocumentException e) {
				log.error(e.getMessage());
			}
		}
		return res;
	}








	public List<AllDSInfo> infoDataStructures() {

		List<AllDSInfo> response = new ArrayList<AllDSInfo>();

		List<String> elems = executeQuery("for $x in distinct-values(collection('/db/DRIVER')//RESOURCE_TYPE/@value)\n" +
				"let $dates := collection('/db/DRIVER')//RESOURCE_TYPE[@value = $x]/../DATE_OF_CREATION/@value/string(),\n" +
				"$m := max($dates), $c := count($dates)\n" +
				"where ends-with($x, 'DSResourceType')\n" +
				"order by $c descending\n" +
		"return <r name='{$x}' date='{$m}' count='{$c}' />");
		SAXReader xmlParser = new SAXReader();

		for (String xml : elems) {
			Document doc;
			try {
				doc = xmlParser.read(new StringReader(xml));
				String name = doc.valueOf("//r/@name");
				if (name.endsWith("DSResourceType")) {
					AllDSInfo info = new AllDSInfo(name.replace("DSResourceType", ""),
							doc.valueOf("//r/@date"),
							Integer.parseInt(doc.valueOf("//r/@count")));
					response.add(info);
				}
			} catch (DocumentException e) {}

		}

		return response;
	}



	public List<Map<String, String>> listRecentDataStructures(int limit) {
		String query = "subsequence(" +
		"for $x in collection('/db/DRIVER') " +
		"where ends-with($x//RESOURCE_TYPE/@value, 'DSResourceType') " +
		"order by $x//DATE_OF_CREATION/@value descending " +
		"return $x,0,"+limit+")";
		List<String> elems = executeQuery(query);

		return _prepareListDataStructures(elems, null);
	}



	public List<Map<String, String>> listDataStructures(String type) {
		if (!type.endsWith("ResourceType")) type += "DSResourceType";

		List<String> elems = executeQuery("for $x in collection('/db/DRIVER/')\n" +
				"where $x//RESOURCE_TYPE/@value/string() = '"+ type +"'\n" +
				"order by $x//DATE_OF_CREATION/@value/string()\n" +
		"return $x");

		return _prepareListDataStructures(elems, type);
	}

	private List<Map<String, String>> _prepareListDataStructures(List<String> list, String type) {
		boolean mixed = false;
		if (type == null) mixed = true;

		List<Map<String, String>> response = new ArrayList<Map<String,String>>();
		SAXReader xmlParser = new SAXReader();
		for (String xml : list) {
			Document doc;
			try {
				doc = xmlParser.read(new StringReader(xml));
				if (mixed) type = doc.valueOf("//RESOURCE_TYPE/@value");
				Map<String,String> row = new HashMap<String,String>();
				row.put("Identifier", doc.valueOf("//RESOURCE_IDENTIFIER/@value"));
				row.put("Last Update", doc.valueOf("//DATE_OF_CREATION/@value"));
				row.put("Type", type.replaceAll("DSResourceType", ""));
				Properties props = new Properties();
				InputStream in = this.getClass().getResourceAsStream("datastructures.prop");
				props.load(in);
				in.close();
				for (Object  k : props.keySet()) {
					String key = k.toString();
					if (key.startsWith(type + ".")) {
						row.put(key.substring(type.length() + 1), doc.valueOf(props.getProperty(key)));
					}
				}
				response.add(row);
			} catch (Exception e) {
				log.error(e.getMessage());
			}
		}
		return response;
	}

	public List<RepositoryStatusInfo> listRepositories() {
		List<RepositoryStatusInfo> response = new ArrayList<RepositoryStatusInfo>();

		String xquery = "for $e in collection('/db/DRIVER/RepositoryServiceResources/RepositoryServiceResourceType') " +
		"return concat('0','|',$e//RESOURCE_IDENTIFIER/@value/string(),'|',$e//OFFICIAL_NAME,'|',$e//COUNTRY,'|',$e//NUMBER_OF_OBJECTS,'|',$e//LATITUDE,'|',$e//LONGITUDE,'|')" +
		", " +
		"for $e in collection('/db/DRIVER/PendingRepositoryResources/RepositoryServiceResourceType') "  +
		"return concat('1','|',$e//RESOURCE_IDENTIFIER/@value/string(),'|',$e//OFFICIAL_NAME,'|',$e//COUNTRY,'|',$e//NUMBER_OF_OBJECTS,'|',$e//LATITUDE,'|',$e//LONGITUDE,'|')";

		List<String> elems = executeQuery(xquery);

		String xqueryStored = "for $h in collection('/db/DRIVER/HarvestingInstanceDSResources/HarvestingInstanceDSResourceType') " +
		"return concat($h//CONFIGURATION/REPOSITORY_SERVICE_IDENTIFIER,'|dc_',$h//MDSTORE_DS_IDENTIFIER[../METADATA_FORMAT/text() = 'oai_dc'],'|dmf_',$h//MDSTORE_DS_IDENTIFIER[../METADATA_FORMAT/text() = 'DMF'])";

		String xqueryIndexed = "for $x in collection('/db/DRIVER/ManagerServiceMapDSResources/ManagerServiceMapDSResourceType') return $x//INDEX/MDSTORE/@id/string()";

		Map<String,String> statusImages = calculateStatusImages(executeQuery(xqueryStored), executeQuery(xqueryIndexed));

		for (String s : elems) {
			RepositoryStatusInfo repo = new RepositoryStatusInfo();
			String[] arr = s.split("\\|");
			if (arr[0].equals("0"))	repo.setPending(false);
			else 	                repo.setPending(true);
			repo.setIdentifier(arr[1]);
			repo.setName(arr[2]);
			repo.setCountry(arr[3]);
			repo.setSize(Integer.parseInt(arr[4]));
			repo.setLat(Float.parseFloat(arr[5]));
			repo.setLng(Float.parseFloat(arr[6]));
			repo.setDeleted(false);
			if      (repo.isPending())                 repo.setStatusImage("noinfo.png");
			else if (statusImages.containsKey(arr[1])) repo.setStatusImage(statusImages.get(arr[1]));
			else                                       repo.setStatusImage("allFail.png");
			response.add(repo);
		}
		return response;
	}

	private Map<String, String> calculateStatusImages(List<String> list, List<String> indexed) {
		Map<String, String> res = new HashMap<String, String>();

		for (String	line : list) {
			String[] arr = line.split("\\|");
			String repoId = arr[0];
			String dcId = arr[1].substring(3); //remove dc_ from beginning
			String dmfId = arr[2].substring(4); //remove dmf_ from beginning

			String image = "allFail.png";

			boolean dcMissing  = isMissingMDF(dcId);
			boolean dmfMissing = isMissingMDF(dmfId);

			if (dcMissing && dmfMissing) {
				image = "noinfo.png";
			} else if (dcMissing) {
				if (indexed.contains(dmfId)) image = "dmfOK.png";
				else                         image = "dmfFail.png";
			} else if (dmfMissing) {
				if (indexed.contains(dcId)) image = "dcOK.png";
				else                  image = "dcFail.png";
			} else {
				boolean dcOk = indexed.contains(dcId);
				boolean dmfOk = indexed.contains(dmfId);
				if      ( dcOk &&  dmfOk) image = "allOK.png";
				else if (!dcOk &&  dmfOk) image = "fail-OK.png";
				else if ( dcOk && !dmfOk) image = "OK-fail.png";
			}
			res.put(repoId, image);
		}

		return res;
	}

	private boolean isMissingMDF(String id) {
		if (id == null)	return true;
		if (id.equals("")) return true;
		return false;
	}


	public RepositoryDetailsInfo getRepositoryDetailsInfo(String id) throws MyGwtException {
		return Common.getRepoDetails(id, isLookUpLocator.getService());
	}



	public List<MDStoreInfo> getMDStoreInfo(List<String> ids) throws MyGwtException {

		List<MDStoreInfo> res = new ArrayList<MDStoreInfo>();


		for (String id :  ids) {
			MDStoreInfo info = Common.getMDStoreInfo(id, isLookUpLocator.getService());
			res.add(info);
		}
		return res;
	}

	public Map<String, String> loadCountries() throws MyGwtException {
		Map<String,String> map = new HashMap<String, String>();
		String xquery = "for $x in collection('/db/DRIVER/VocabularyDSResources/VocabularyDSResourceType')//CONFIGURATION[./VOCABULARY_NAME='Names of Countries']/TERMS/TERM return concat($x/@encoding,'|',$x/@english_name)";
		for (String line : executeQuery(xquery)) {
			String[] arr = line.split("\\|");
			if (arr.length == 2) {
				map.put(arr[0], arr[1]);
			}
		}
		return map;
	}

	public List<IndexInfo> getOldOrDuplicatedIndexes() throws MyGwtException {

		List<IndexInfo> res = new ArrayList<IndexInfo>();

		String queryOLD = "for $mi in collection('/db/DRIVER/ManagerServiceMapDSResources/ManagerServiceMapDSResourceType')//INDEX," +
		"$md in collection('/db/DRIVER/MDStoreDSResources/MDStoreDSResourceType')//RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value = $mi/MDSTORE/@id]," +
		"$ix in collection('/db/DRIVER/IndexDSResources/IndexDSResourceType')//RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value = $mi/@id]," +
		"$hi in collection('/db/DRIVER/HarvestingInstanceDSResources/HarvestingInstanceDSResourceType')//RESOURCE_PROFILE[.//AGGREGATING_UNIT/MDSTORE_DS_IDENTIFIER = $mi/MDSTORE/@id]," +
		"$re in collection('/db/DRIVER/RepositoryServiceResources/RepositoryServiceResourceType')//RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value = $hi//REPOSITORY_SERVICE_IDENTIFIER] " +
		"where $md//LAST_STORAGE_DATE/string() != ''" +
		"and xs:dateTime($ix//INDEX_LAST_UPDATE/string()) < xs:dateTime($md//DATE_OF_CREATION/@value/string()) " +
		//"order by xs:integer($md//NUMBER_OF_RECORDS) descending " +
		"return concat(" +
		"$re//RESOURCE_IDENTIFIER/@value/string(),'|', " +
		"$re//OFFICIAL_NAME,'|'," +
		"$re//COUNTRY,'|'," +
		"$hi//RESOURCE_IDENTIFIER/@value/string(),'|'," +
		"$ix//RESOURCE_IDENTIFIER/@id/string(),'|'," +
		"$ix//INDEX_SIZE,'|'," +
		"$ix//DATE_OF_CREATION/@value)";

		for (String s : executeQuery(queryOLD)) {
			String[] arr = s.split("\\|");

			String repoId = arr[0];
			String repoName  = arr[1];
			String repoCountry = arr[2];
			String hiid  = arr[3];
			String indexId  = arr[4];
			int indexSize  = Integer.parseInt(arr[5]);
			String indexDate = arr[6];

			IndexInfo info = new IndexInfo(indexId, indexSize, false, false, repoId, repoName, repoCountry, hiid, indexDate);
			res.add(info);
		}


		String queryDupl = "for $ma in collection('/db/DRIVER/ManagerServiceMapDSResources/ManagerServiceMapDSResourceType')//INDEX," +
		"$mb in collection('/db/DRIVER/ManagerServiceMapDSResources/ManagerServiceMapDSResourceType')//INDEX[@id != $ma/@id and MDSTORE/@id = $ma/MDSTORE/@id]," +
		"$ix in collection('/db/DRIVER/IndexDSResources/IndexDSResourceType')//RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value = $mb/@id]," +
		"$hi in collection('/db/DRIVER/HarvestingInstanceDSResources/HarvestingInstanceDSResourceType')//RESOURCE_PROFILE[.//AGGREGATING_UNIT/MDSTORE_DS_IDENTIFIER = $mb/MDSTORE/@id]," +
		"$re in collection('/db/DRIVER/RepositoryServiceResources/RepositoryServiceResourceType')//RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value = $hi//REPOSITORY_SERVICE_IDENTIFIER] " +
		"order by $re//OFFICIAL_NAME,xs:dateTime($ix//DATE_OF_CREATION/@value) descending " +
		"return concat(" +
		"$re//RESOURCE_IDENTIFIER/@value/string(),'|', " +
		"$re//OFFICIAL_NAME,'|'," +
		"$re//COUNTRY,'|'," +
		"$hi//RESOURCE_IDENTIFIER/@value/strigetRepoStatusInfong(),'|'," +
		"$ix//RESOURCE_IDENTIFIER/@id/string(),'|'," +
		"$ix//INDEX_SIZE,'|'," +
		"$ix//DATE_OF_CREATION/@value)";

		for (String s : executeQuery(queryDupl)) {
			String[] arr = s.split("\\|");

			String repoId = arr[0];
			String repoName  = arr[1];
			String repoCountry = arr[2];
			String hiid  = arr[3];
			String indexId  = arr[4];
			int indexSize  = Integer.parseInt(arr[5]);
			String indexDate = arr[6];

			IndexInfo info = new IndexInfo(indexId, indexSize, true, true, repoId, repoName, repoCountry, hiid, indexDate);
			res.add(info);
		}
		return res;
	}





	private List<Map<String, String>> _clean_repo_without_hi(boolean delete) {
		List<Map<String, String>> res = new ArrayList<Map<String,String>>();

		String query = "for $repo in " +
		"collection('/db/DRIVER/RepositoryServiceResources/RepositoryServiceResourceType')//RESOURCE_IDENTIFIER/@value/string() " +
		"where not(contains(collection('/db/DRIVER/HarvestingInstanceDSResources/HarvestingInstanceDSResourceType')//REPOSITORY_SERVICE_IDENTIFIER/text(),$repo)) " +
		"return $repo";

		for (String item : executeQuery(query)) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("id", item);
			res.add(map );
		};
		return res;
	}

	private List<Map<String, String>> _clean_up_hi_without_repo(boolean delete) {
		List<Map<String, String>> res = new ArrayList<Map<String,String>>();

		String query = "for $hi in " +
		"collection('/db/DRIVER/HarvestingInstanceDSResources/HarvestingInstanceDSResourceType') " +
		"where not(contains(collection('/db/DRIVER/RepositoryServiceResources/RepositoryServiceResourceType')//RESOURCE_IDENTIFIER/@value/string(),$hi//REPOSITORY_SERVICE_IDENTIFIER/text())) " +
		"return $hi//RESOURCE_IDENTIFIER/@value/string()";

		for (String item : executeQuery(query)) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("id", item);
			res.add(map );
		};
		return res;
	}

	private List<Map<String, String>> _clean_up_hi_without_store(boolean delete) {
		List<Map<String, String>> res = new ArrayList<Map<String,String>>();

		String query = "for $hi in " +
		"collection('/db/DRIVER/HarvestingInstanceDSResources/HarvestingInstanceDSResourceType') " +
		"where not(contains(collection('/db/DRIVER/MDStoreDSResources/MDStoreDSResourceType')//RESOURCE_IDENTIFIER/@value/string(),$hi//MDSTORE_DS_IDENTIFIER/text())) " +
		"return $hi//RESOURCE_IDENTIFIER/@value/string()";

		for (String item : executeQuery(query)) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("id", item);
			res.add(map );
		};

		return res;
	}

	private List<Map<String, String>> _cleanUP_indices_not_managed(boolean delete) {
		List<Map<String, String>> res = new ArrayList<Map<String,String>>();

		String query = "for $idx in " +
		"collection('/db/DRIVER/IndexDSResources/IndexDSResourceType')//RESOURCE_IDENTIFIER/@value/string() " +
		"where not(contains(collection('/db/DRIVER/ManagerServiceMapDSResources/ManagerServiceMapDSResourceType')//INDEX_MAP/INDEX/@id/string(), $idx)) " +
		"return $idx";

		for (String item : executeQuery(query)) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("id", item);
			res.add(map );
		};

		return res;
	}

	private List<Map<String, String>> _cleanUP_stores_without_hi(boolean delete) {
		List<Map<String, String>> res = new ArrayList<Map<String,String>>();

		String query = "for $md  in " +
		"collection('/db/DRIVER/MDStoreDSResources/MDStoreDSResourceType')//RESOURCE_IDENTIFIER/@value/string() " +
		"where not(contains(collection('/db/DRIVER/HarvestingInstanceDSResources/HarvestingInstanceDSResourceType')//MDSTORE_DS_IDENTIFIER/text(),$md)) " +
		"return $md";

		for (String item : executeQuery(query)) {
			Map<String, String> map = new HashMap<String, String>();
			map.put("id", item);
			res.add(map );
		};

		return res;
	}

	private List<Map<String, String>> _cleanUP_stores_without_index(boolean delete) {
		List<Map<String, String>> res = new ArrayList<Map<String,String>>();
		String query = "for $md in " +
		"collection('/db/DRIVER/MDStoreDSResources/MDStoreDSResourceType') " +
		"where not(contains(collection('/db/DRIVER/ManagerServiceMapDSResources/ManagerServiceMapDSResourceType')//INDEX_MAP/INDEX/MDSTORE/@id/string(),$md//RESOURCE_IDENTIFIER/@value/string())) " +
		"order by $md//METADATA_FORMAT/text(),$md//STATUS/NUMBER_OF_RECORDS/number() descending " +
		"return concat($md//METADATA_FORMAT/text(),'|',$md//STATUS/NUMBER_OF_RECORDS/text(),'|',$md//RESOURCE_IDENTIFIER/@value/string(),'|')";

		for (String item : executeQuery(query)) {
			Map<String, String> map = new HashMap<String, String>();
			String[] arr = item.split("\\|");
			if (arr.length == 3) {
				map.put("type", arr[0]);
				map.put("size", arr[1]);
				map.put("id", arr[2]);
			}

			res.add(map );
		};

		return res;
	}

	public Map<String, List<Map<String, String>>> cleanUP(Boolean delete) throws MyGwtException {
		Map<String,List<Map<String,String>>> res = new HashMap<String,List<Map<String,String>>>();

		res.put("MDSTORES without index - to FEED (manually)", _cleanUP_stores_without_index(delete));
		res.put("MDSTORES without HI - Cleaning will DELETE them", _cleanUP_stores_without_hi(delete));
		res.put("Indices not registered in the ManagerServiceMap - Cleaning will DELETE them", _cleanUP_indices_not_managed(delete));
		res.put("HIs without MDSTORE - Cleaning will DELETE them", _clean_up_hi_without_store(delete));
		res.put("HIs without REPOSITORY - Cleaning will DELETE them", _clean_up_hi_without_repo(delete));
		res.put("REPOs without HI - Cleaning will INVALIDATE them", _clean_repo_without_hi(delete));

		return res;
	}

	public List<AggregatorInfo> listAggregators() throws MyGwtException {
		List<AggregatorInfo> list = new ArrayList<AggregatorInfo>();

		try {
			String query = 
				"for $aggr in " +
				"collection('/db/DRIVER/ServiceResources/AggregatorServiceResourceType') " +
				"return $aggr";

			SAXReader reader = new SAXReader();

			for (String item : executeQuery(query)) {	
				Document doc = reader.read(new StringReader(item));

				String name = doc.valueOf("//SERVICE_PROPERTIES/PROPERTY[@key='name']/@value");
				if ((name == null)||(name.isEmpty())) {
					name = "unknown";
				}
				String country = doc.valueOf("//SERVICE_PROPERTIES/PROPERTY[@key='country']/@value");
				if ((country == null)||(country.isEmpty())) {
					country = "unknown";
				}
				String host = doc.valueOf("//SERVICE_PROPERTIES/PROPERTY[@key='host']/@value");
				if ((host == null)||(host.isEmpty())) {
					host = "unknown";
				}
				String url = doc.valueOf("//SERVICE_PROPERTIES/PROPERTY[@key='url']/@value");
				if ((url != null)&&(url.length() > 0)) {
					list.add(new AggregatorInfo(name, country, url, host));
				}
			}
		} catch (Exception e) {
			log.error(e.getMessage());
		}
		return list;
	}

	@Override
	public List<BlackBoardInfo> listBlackboards() throws MyGwtException {
		List<BlackBoardInfo> list = new ArrayList<BlackBoardInfo>();
		SAXReader reader = new SAXReader();
		try {
			for (String xml : isLookUpLocator.getService().quickSearchProfile("for $x in collection('/db/DRIVER/ServiceResources')//MESSAGE return <message>{$x/../../..//RESOURCE_TYPE}{$x/../../..//RESOURCE_IDENTIFIER}{$x}</message>")) {
				BlackBoardInfo info = new BlackBoardInfo();
				Document doc = reader.read(new StringReader(xml));
				info.setProfId(doc.valueOf(".//RESOURCE_IDENTIFIER/@value"));
				info.setMessageId(doc.valueOf(".//@id"));
				info.setResourceType(doc.valueOf(".//RESOURCE_TYPE/@value"));
				info.setAction(doc.valueOf(".//ACTION"));
				info.setDate(doc.valueOf(".//@date"));
				info.setActionStatus(doc.valueOf(".//ACTION_STATUS"));
				info.setError(doc.valueOf(".//PARAMETER[@name='error']/@value"));
				list.add(info);
			}
		} catch (Exception e) {
			throw new MyGwtException();
		}
		return list;
	}

}
