package eu.dnetlib.enabling.ui.server;

import java.io.StringReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.ui.common.beans.MDStoreInfo;
import eu.dnetlib.enabling.ui.common.beans.RepositoryAggrInfo;
import eu.dnetlib.enabling.ui.common.beans.RepositoryMDStoreInfo;
import eu.dnetlib.enabling.ui.common.services.MyGwtException;
import eu.dnetlib.miscutils.datetime.DateUtils;

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

	
	public static MDStoreInfo getMDStoreInfo(String id, ISLookUpService lu) throws MyGwtException {
		
		SAXReader xmlParser = new SAXReader();
		MDStoreInfo info = new MDStoreInfo();

		try {

			String prof = lu.getResourceProfile(id);
			Document doc = xmlParser.read(new StringReader(prof));


			String mdName = doc.valueOf("//CONFIGURATION/METADATA_FORMAT");
			int mdSize = Integer.parseInt(doc.valueOf("//STATUS/NUMBER_OF_RECORDS"));
			String mdDate = doc.valueOf("//STATUS/LAST_STORAGE_DATE");

			URL url = new URL(doc.valueOf("//RESOURCE_URI/@value"));

			info.setIdentifier(id);
			info.setAddress(url.getHost() + ":" + url.getPort());
			info.setMdName(mdName);
			info.setSize(mdSize);
			info.setLastDate(mdDate);

			String idIndexQuery = "for $x in collection('/db/DRIVER/ManagerServiceMapDSResources/ManagerServiceMapDSResourceType') return $x//INDEX[./MDSTORE/@id/string() = '" + id + "']/@id/string()";

			try {
				String idIndex = lu.getResourceProfileByQuery(idIndexQuery);
				String indexProf = lu.getResourceProfile(idIndex);

				Document docIndex = xmlParser.read(new StringReader(indexProf));
				int indexSize = Integer.parseInt(docIndex.valueOf("//CONFIGURATION/INDEX_SIZE"));


				Date idxDate = (new DateUtils()).parse(docIndex.valueOf("//STATUS/INDEX_LAST_UPDATE"));

				info.setIndex(idIndex);
				info.setIndexSize(indexSize);
				info.setIndexUpdated(idxDate.after((new DateUtils()).parse(mdDate)) && (indexSize <= mdSize));
			} catch (Exception e) {
				info.setIndex("");
				info.setIndexSize(0);
				info.setIndexUpdated(false);
			}

		} catch (Exception e) {
			log.error("Failed MDStoreInfo: "+e.getMessage());
			throw (new MyGwtException(e.getMessage(), "Retry later"));
		}
		return info;
	}
	
	
	public static RepositoryAggrInfo getRepoStatusInfo(String id, ISLookUpService lu) throws MyGwtException {
		RepositoryAggrInfo info = new RepositoryAggrInfo();
		SAXReader xmlParser = new SAXReader();
		try {
			String prof = lu.getResourceProfileByQuery("for $x in collection('/db/DRIVER/HarvestingInstanceDSResources/HarvestingInstanceDSResourceType') where $x//CONFIGURATION/REPOSITORY_SERVICE_IDENTIFIER/text() = '" + id + "' return $x");

			Document doc = xmlParser.read(new StringReader(prof));

			String aggrID = doc.valueOf("//AGGREGATOR_SERVICE_IDENTIFIER");

			String hiid = doc.valueOf("//RESOURCE_IDENTIFIER/@value");
			List<RepositoryMDStoreInfo> mdf = new ArrayList<RepositoryMDStoreInfo>();

			for (Object unit : doc.selectNodes("//HARVESTING_UNITS/HARVESTING_UNIT")) {
				RepositoryMDStoreInfo mdInfo = _mdInfoFromAggrUnit((Element) unit, "HARV");
				mdf.add(mdInfo);
			}

			for (Object unit : doc.selectNodes("//AGGREGATING_UNITS/AGGREGATING_UNIT")) {;
				RepositoryMDStoreInfo mdInfo = _mdInfoFromAggrUnit((Element) unit, "AGGR");
				mdf.add(mdInfo);
			}

			for (Object unit : doc.selectNodes("//REPLICA_UNITS/REPLICA_UNIT")) {
				RepositoryMDStoreInfo mdInfo = _mdInfoFromAggrUnit((Element) unit, "REPL");
				mdf.add(mdInfo);
			}

			
			String aggrURL = "";
			String aggrName = "";
			if (aggrID.length() > 0) {
				try {
					Document doc2 = xmlParser.read(new StringReader(lu.getResourceProfile(aggrID)));
					aggrURL = doc2.valueOf("//SERVICE_PROPERTIES/PROPERTY[@key='url']/@value");
					aggrName = doc2.valueOf("//SERVICE_PROPERTIES/PROPERTY[@key='name']/@value");
				} catch (Exception e) {
					log.error("Aggregator profile not found");
				}
			}
			
			info.setRepoId(id);
			info.setAggrURL(aggrURL);
			info.setAggrName(aggrName);
			info.setHiid(hiid);
			info.setFormats(mdf);

			
		} catch (Exception e) {
			log.error("Failed RepositoryAggrInfo: "+e.getMessage());
			throw (new MyGwtException(e.getMessage(), "Probably Harvesting Instance is missing, try to reharvest."));
		}
		return info;
	}
	
	private static RepositoryMDStoreInfo _mdInfoFromAggrUnit(Element unit, String type) {
		RepositoryMDStoreInfo mdInfo = new RepositoryMDStoreInfo();
		mdInfo.setMdName(unit.valueOf("./METADATA_FORMAT"));
		mdInfo.setMdstoreId(unit.valueOf("./MDSTORE_DS_IDENTIFIER"));
		mdInfo.setType(type);
		mdInfo.setSize(0);
		if      (type.equals("HARV")) mdInfo.setLastDate(unit.valueOf("./LAST_HARVESTING_DATE"));
		else if (type.equals("AGGR")) mdInfo.setLastDate(unit.valueOf("./LAST_AGGREGATING_DATE"));
		else if (type.equals("REPL")) mdInfo.setLastDate(unit.valueOf("./LAST_REPLICA_DATE"));
		return mdInfo;
	}
}
