package eu.dnetlib.enabling.datasources;

import com.google.common.base.Function;
import eu.dnetlib.enabling.datasources.rmi.DatasourceDesc;
import eu.dnetlib.enabling.datasources.rmi.IfaceDesc;
import eu.dnetlib.miscutils.datetime.DateUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

public class DatasourceDescToProfile implements Function<DatasourceDesc, String> {
	private static final Log log = LogFactory.getLog(DatasourceDescToProfile.class);

	public DatasourceDescToProfile(final String environment) {
		this.environment = environment;
	}

	private String environment;

	public static String convert(final DatasourceDesc ds, String environment) throws Exception {
		final Element root = DocumentHelper.createElement("RESOURCE_PROFILE");

		final Element header = root.addElement("HEADER");
		header.addElement("RESOURCE_IDENTIFIER").addAttribute("value", "");
		header.addElement("RESOURCE_TYPE").addAttribute("value", "RepositoryServiceResourceType");
		header.addElement("RESOURCE_KIND").addAttribute("value", "RepositoryServiceResources");
		header.addElement("RESOURCE_URI").addAttribute("value", "");
		header.addElement("DATE_OF_CREATION").addAttribute("value", DateUtils.now_ISO8601());
		header.addElement("PROTOCOL");

		final Element body = root.addElement("BODY");
		final Element conf = body.addElement("CONFIGURATION");
		conf.addElement("DATASOURCE_TYPE").setText(ds.getDatasourceClass());

		final Element origId = conf.addElement("DATASOURCE_ORIGINAL_ID");
		origId.addAttribute("provenance", "D-NET");
		origId.setText(ds.getId());

		conf.addElement("DATASOURCE_AGGREGATED").setText("false");
		conf.addElement("ENVIRONMENTS").addElement("ENVIRONMENT").setText(environment);
		conf.addElement("TYPOLOGY").setText(""+ds.getTypology());
		conf.addElement("MAX_SIZE_OF_DATASTRUCTURE").setText("0");
		conf.addElement("AVAILABLE_DISKSPACE").setText("0");
		conf.addElement("MAX_NUMBER_OF_DATASTRUCTURE").setText("0");

		final String officialName = ds.getOfficialName();
		conf.addElement("OFFICIAL_NAME").setText(officialName);
		String englishName = ds.getEnglishName();
		conf.addElement("ENGLISH_NAME").setText(StringUtils.isNotBlank(englishName) ? englishName : officialName);
		conf.addElement("ICON_URI").setText(""+ds.getLogoUrl());
		conf.addElement("COUNTRY").setText(ds.getCountryCode());

		final Element location = conf.addElement("LOCATION");
		location.addElement("LONGITUDE").setText("" + ds.getLongitude());
		location.addElement("LATITUDE").setText("" + ds.getLatitude());
		location.addElement("TIMEZONE").setText("" + ds.getTimezone());

		conf.addElement("REPOSITORY_WEBPAGE").setText(ds.getWebsiteUrl());
		conf.addElement("REPOSITORY_INSTITUTION").setText(ds.getOrganization());
		conf.addElement("ADMIN_INFO").setText(ds.getContactEmail());

		final Element ifaces = conf.addElement("INTERFACES");
		for (IfaceDesc ifc : ds.getInterfaces()) {
			ifaces.add(IfaceDescToNode.convert(ifc));
		}
		final Element extraFields = conf.addElement("EXTRA_FIELDS");
		addExtraField(extraFields, "ACTIVATION_ID", ds.getActivationId());
		addExtraField(extraFields, "NamespacePrefix", ds.getNamespacePrefix());
		addExtraField(extraFields, "aggregatorName", ds.getAggregator());
		addExtraField(extraFields, "dateOfCollection", "" + ds.getDateOfCollection());
		addExtraField(extraFields, "dateOfValidation", "" + ds.getDateOfValidation());
		conf.addElement("REGISTERED_BY");

		final Element status = body.addElement("STATUS");
		status.addElement("NUMBER_OF_OBJECTS").setText("0");
		status.addElement("LAST_UPDATE").addAttribute("value", DateUtils.now_ISO8601());

		final Element qos = body.addElement("QOS");
		qos.addElement("AVAILABILITY").setText("0");
		qos.addElement("CAPACITY");
		qos.addElement("THROUGHPUT").setText("0");

		body.addElement("SECURITY_PARAMETERS");
		body.addElement("BLACKBOARD");

		return root.asXML();
	}

	private static void addExtraField(final Element extraFields, final String field, final String value) {
		final Element f = extraFields.addElement("FIELD");
		f.addElement("key").setText(field);
		f.addElement("value").setText(value != null ? value : "");
	}

	@Override
	public String apply(final DatasourceDesc ds) {
		try {
			return DatasourceDescToProfile.convert(ds, environment);
		} catch (Exception e) {
			log.error("Error convering profile", e);
			return null;
		}
	}
}
