package eu.dnetlib.enabling.datasources;

import java.util.Map.Entry;
import java.util.function.Function;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;

import eu.dnetlib.clients.dsManager.DatasourceDesc;
import eu.dnetlib.clients.dsManager.IfaceDesc;
import eu.dnetlib.miscutils.datetime.DateUtils;

public class DatasourceDescToProfile implements Function<DatasourceDesc, String> {

	private static final Log log = LogFactory.getLog(DatasourceDescToProfile.class);

	public static String convert(final DatasourceDesc ds) 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", "datasource");
		header.addElement("RESOURCE_KIND").addAttribute("value", "entity");
		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");
		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");

		conf.addElement("OFFICIAL_NAME").setText(ds.getOfficialName());
		conf.addElement("ENGLISH_NAME").setText(ds.getEnglishName());
		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 (final IfaceDesc ifc : ds.getInterfaces()) {
			ifaces.add(ifaceDescToNode(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");

		System.out.println("aaaaaaaaaaaaaa " + root.asXML());

		return root.asXML();
	}

	public static Node ifaceDescToNode(final IfaceDesc iface) throws Exception {

		final Element ifcNode = DocumentHelper.createElement("INTERFACE");
		ifcNode.addAttribute("id", iface.getId());
		ifcNode.addAttribute("label", iface.getTypology() + " (" + iface.getCompliance() + ")");
		ifcNode.addAttribute("compliance", iface.getCompliance());
		ifcNode.addAttribute("typology", iface.getTypology());
		ifcNode.addAttribute("contentDescription", iface.getContentDescription());
		ifcNode.addAttribute("active", Boolean.toString(iface.isActive()));
		ifcNode.addAttribute("removable", Boolean.toString(iface.isRemovable()));

		final Element acProtoNode = ifcNode.addElement("ACCESS_PROTOCOL");

		for (final Entry<String, String> e : iface.getAccessParams().entrySet()) {
			acProtoNode.addAttribute(e.getKey(), e.getValue());
		}
		acProtoNode.setText(iface.getAccessProtocol());

		ifcNode.addElement("BASE_URL").setText(iface.getBaseUrl());;

		for (final Entry<String, String> e : iface.getExtraFields().entrySet()) {
			final Element field = ifcNode.addElement("INTERFACE_EXTRA_FIELD");
			field.addAttribute("name", e.getKey());
			field.setText(e.getValue());
		}

		return ifcNode;
	}

	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);
	}

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