package eu.dnetlib.data.mdstore.modular;

import com.google.common.collect.Lists;
import eu.dnetlib.data.mdstore.MDStoreServiceException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpDocumentNotFoundException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
import org.springframework.beans.factory.annotation.Autowired;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import java.io.ByteArrayInputStream;
import java.util.List;

public class MDStoreUtils {

    /**
     * service locator.
     */
    @Autowired
    private UniqueServiceLocator serviceLocator;

    public List<MDFormatDescription> getField(final String format, final String layout) throws MDStoreServiceException {

        String xquery = "for $x in collection('/db/DRIVER/MDFormatDSResources/MDFormatDSResourceType')/RESOURCE_PROFILE/BODY[CONFIGURATION/NAME='" + format + "'] return $x/STATUS/LAYOUTS/LAYOUT[@name='" + layout
                + "']/FIELDS";

        try {
            String result = serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(xquery);
            final List<MDFormatDescription> mdformat = Lists.newArrayList();
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder;
            builder = factory.newDocumentBuilder();
            Document doc = builder.parse(new ByteArrayInputStream(result.getBytes()));
            XPathFactory xPathFactory = XPathFactory.newInstance();
            XPath myXpath = xPathFactory.newXPath();
            XPathExpression expression = myXpath.compile("//FIELD");
            Object values = expression.evaluate(doc, XPathConstants.NODESET);
            NodeList v = (NodeList) values;
            for (int i = 0; i < v.getLength(); i++) {
                Node currentItem = v.item(i);
                NamedNodeMap attributes = currentItem.getAttributes();
                String name = null;
                String xpath = null;
                if (attributes.getNamedItem("name") != null) {
                    name = attributes.getNamedItem("name").getNodeValue();
                }
                if (attributes.getNamedItem("xpath") != null) {
                    xpath = attributes.getNamedItem("xpath").getNodeValue();
                }
                if (attributes.getNamedItem("value") != null) {
                    xpath = attributes.getNamedItem("value").getNodeValue();
                }

                MDFormatDescription currentMdFormat = new MDFormatDescription();
                currentMdFormat.setName(name);
                currentMdFormat.setXpath(xpath);
                mdformat.add(currentMdFormat);
            }
            return mdformat;

        } catch (ISLookUpDocumentNotFoundException e1) {
            return null;
        } catch (ISLookUpException e1) {
            return null;
        } catch (Exception e) {
            throw new MDStoreServiceException("Error on retrieving field from mdformat", e);
        }

    }
}

