package eu.dnetlib.datasource.common.utils;

import java.io.StringReader;
import java.util.Map;

import javax.annotation.Resource;

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

import com.google.common.collect.Maps;

import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
import eu.dnetlib.enabling.locators.UniqueServiceLocator;

@Deprecated
public class DefaultDatasourceUpdater implements DatasourceUpdater {

	public static final String OVERRIDING_COMPLIANCE_FIELD = "overriding_compliance";

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

	private static final String REPOSITORY_RESOURCE_TYPE = "RepositoryServiceResourceType";

	@Resource
	private UniqueServiceLocator serviceLocator;

	@Override
	public boolean updateApiExtraFields(final String repoId, final String ifaceId, final Map<String, String> fields) throws DatasourceUpdaterException {
		try {
			final String profile = serviceLocator.getService(ISLookUpService.class).getResourceProfile(repoId);

			final SAXReader reader = new SAXReader();
			final Document doc = reader.read(new StringReader(profile));

			final Element iface = (Element) doc.selectSingleNode("//INTERFACE[@id='" + ifaceId + "']");
			if (iface != null) {

				while (iface.selectNodes("./INTERFACE_EXTRA_FIELD").size() > 0) {
					iface.selectSingleNode("./INTERFACE_EXTRA_FIELD").detach();
				}
				for (Map.Entry<String, String> e : fields.entrySet()) {
					if (e.getValue() != null && !e.getValue().isEmpty()) {
						final Element field = iface.addElement("INTERFACE_EXTRA_FIELD");
						field.addAttribute("name", e.getKey());
						field.addText(e.getValue());
					}
				}
				serviceLocator.getService(ISRegistryService.class).updateProfile(repoId, doc.asXML(), REPOSITORY_RESOURCE_TYPE);
			} else {
				log.error("Invalid interface: " + ifaceId);
				throw new DatasourceUpdaterException("Missing interface: " + ifaceId);
			}
		} catch (Exception e) {
			log.error("Error updating API of profile: " + repoId);
			throw new DatasourceUpdaterException("Error updating API of profile: " + repoId, e);
		}
		return true;

	}

	@Override
	public boolean updateApiAccessParams(final String repoId, final String ifaceId, final Map<String, String> params) throws DatasourceUpdaterException {
		try {
			final String profile = serviceLocator.getService(ISLookUpService.class).getResourceProfile(repoId);

			final SAXReader reader = new SAXReader();
			final Document doc = reader.read(new StringReader(profile));

			final Element accessNode = (Element) doc.selectSingleNode("//INTERFACE[@id='" + ifaceId + "']/ACCESS_PROTOCOL");
			if (accessNode != null) {
				while (accessNode.attributes().size() > 0) {
					accessNode.selectSingleNode("@*").detach();
				}
				for (Map.Entry<String, String> e : params.entrySet()) {
					if (e.getValue() != null && !e.getValue().isEmpty()) {
						if (e.getKey().equalsIgnoreCase("baseUrl")) {
							doc.selectSingleNode("//INTERFACE[@id='" + ifaceId + "']/BASE_URL").setText(e.getValue());
						} else {
							accessNode.addAttribute(e.getKey(), e.getValue());
						}
					}
				}
				serviceLocator.getService(ISRegistryService.class).updateProfile(repoId, doc.asXML(), REPOSITORY_RESOURCE_TYPE);
			} else {
				log.error("Invalid interface: " + ifaceId);
				throw new DatasourceUpdaterException("Missing interface: " + ifaceId);
			}
		} catch (Exception e) {
			log.error("Error updating API of profile: " + repoId);
			throw new DatasourceUpdaterException("Error updating API of profile: " + repoId, e);
		}
		return true;
	}

	@Override
	public boolean overrideCompliance(final String repoId, final String ifaceId, final String compliance) throws DatasourceUpdaterException {
		try {
			final String profile = serviceLocator.getService(ISLookUpService.class).getResourceProfile(repoId);

			final SAXReader reader = new SAXReader();
			final Document doc = reader.read(new StringReader(profile));

			final Element iface = (Element) doc.selectSingleNode("//INTERFACE[@id='" + ifaceId + "']");
			if (iface != null) {
				final Map<String, String> fields = Maps.newHashMap();

				if (!StringUtils.isEmpty(compliance)) {
					fields.put(OVERRIDING_COMPLIANCE_FIELD, compliance);
				}

				while (iface.selectNodes("./INTERFACE_EXTRA_FIELD").size() > 0) {
					final Node node = iface.selectSingleNode("./INTERFACE_EXTRA_FIELD");
					final String name = node.valueOf("@name");

					if (!name.equals(OVERRIDING_COMPLIANCE_FIELD)) {
						fields.put(node.valueOf("@name"), node.getText());
					}
					node.detach();
				}

				for (Map.Entry<String, String> e : fields.entrySet()) {
					if (e.getValue() != null && !e.getValue().isEmpty()) {
						final Element field = iface.addElement("INTERFACE_EXTRA_FIELD");
						field.addAttribute("name", e.getKey());
						field.addText(e.getValue());
					}
				}
				serviceLocator.getService(ISRegistryService.class).updateProfile(repoId, doc.asXML(), REPOSITORY_RESOURCE_TYPE);
			} else {
				log.error("Invalid interface: " + ifaceId);
				throw new DatasourceUpdaterException("Missing interface: " + ifaceId);
			}
		} catch (Exception e) {
			log.error("Error updating API of profile: " + repoId);
			throw new DatasourceUpdaterException("Error updating API of profile: " + repoId, e);
		}

		return true;
	}
}
