package org.datavaultplatform.common.metadata.impl;

import org.datavaultplatform.common.metadata.Dataset;
import org.datavaultplatform.common.metadata.Provider;

import java.util.*;
import java.io.ByteArrayInputStream;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
import org.w3c.dom.*;

public class PureProvider implements Provider {
    
    @Override
    public List<Dataset> getDatasetsForUser(String userID) {
        return null;
    }
    
    @Override
    public Dataset getDataset(String id) {
        return null;
    }
    
    // TODO: HTTP request to endpoint
    // TODO: Support basic auth
    
    // Handle dataset XML namespace mapping
    static class PureNamespaceContent implements NamespaceContext {
        @Override
        public String getNamespaceURI(String prefix) {
            if (prefix.equals("dataset")) {
                return "http://atira.dk/schemas/pure4/wsdl/template/dataset/stable";
            } else if (prefix.equals("core")) {
                return "http://atira.dk/schemas/pure4/model/core/stable";
            } else if (prefix.equals("stab")) {
                return "http://atira.dk/schemas/pure4/model/template/dataset/stable";
            }
            return XMLConstants.NULL_NS_URI;
        }
        @Override
        public String getPrefix(String namespaceURI) {
            throw new UnsupportedOperationException();
        }
        @Override
        public Iterator getPrefixes(String namespaceURI) {
            throw new UnsupportedOperationException();
        }
    }
    
    // Parse XML to build a list of Dataset objects
    private static List<Dataset> parse(String input) {
        
        ArrayList<Dataset> datasets = new ArrayList<>();
        
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            DocumentBuilder db = dbf.newDocumentBuilder();
            ByteArrayInputStream bais = new ByteArrayInputStream(input.getBytes());
            Document dom = db.parse(bais);
            
            XPath xpath = XPathFactory.newInstance().newXPath();
            xpath.setNamespaceContext(new PureNamespaceContent());
            XPathExpression resultExpr = xpath.compile("//core:result");
            XPathExpression contentExpr = xpath.compile("core:content");
            XPathExpression titleExpr = xpath.compile("stab:title/core:localizedString");
            
            // Get a list of datasets
            NodeList results = (NodeList)resultExpr.evaluate(dom, XPathConstants.NODESET);
            
            for (int i=0; i<results.getLength(); i++) {

                Dataset dataset = new Dataset();
                
                // Get the content element and uuid of this dataset
                Node content = (Node)contentExpr.evaluate(results.item(i), XPathConstants.NODE);
                if (content == null) {
                    // Error - content element not found
                    break;
                } else {
                    dataset.setID(content.getAttributes().getNamedItem("uuid").getTextContent());
                }
                
                // Get the title of this dataset
                Node title = (Node)titleExpr.evaluate(content, XPathConstants.NODE);
                if (title != null) {
                    dataset.setName(title.getTextContent());
                }
                
                datasets.add(dataset);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return datasets;
    }
}

@@ -172,12 +172,10 @@
 ava.
-util
+io
 .*;%0A
@@ -190,31 +190,33 @@
 ava.
-io.ByteArrayInputStream
+net.*;%0Aimport java.util.*
 ;%0Aim
@@ -427,269 +427,1048 @@
     
-@Override%0A    public List%3CDataset%3E getDatasetsForUser(String userID) %7B%0A        return null;%0A    %7D%0A    %0A    @Override%0A    public Dataset getDataset(String id) %7B%0A        return null;%0A    %7D%0A    %0A    // TODO: HTTP request to endpoint%0A    // TODO: Support basic auth
+private final String endpoint = %22http://pure-example-url/ws/rest/datasets%22;%0A    %0A    @Override%0A    public List%3CDataset%3E getDatasetsForUser(String userID) %7B%0A        try %7B%0A            String response = query(endpoint);%0A            return parse(response);%0A        %7D catch (Exception e) %7B%0A            e.printStackTrace();%0A        %7D%0A        %0A        return null;%0A    %7D%0A    %0A    @Override%0A    public Dataset getDataset(String id) %7B%0A        return null;%0A    %7D%0A    %0A    // Query the endpoint and retrieve the XML response%0A    // TODO: Support basic auth%0A    private String query(String url) throws Exception %7B%0A       %0A        URL queryURL = new URL(url);%0A        URLConnection conn = queryURL.openConnection();%0A        BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));%0A        String inputLine;%0A       %0A        StringBuilder sb = new StringBuilder();%0A        while ((inputLine = in.readLine()) != null) %7B%0A            sb.append(inputLine);%0A        %7D%0A        in.close();%0A       %0A        return sb.toString();%0A    %7D
 %0A   
@@ -3050,81 +3050,8 @@
 ));%0A
-            XPathExpression resultExpr = xpath.compile(%22//core:result%22);%0A
     
@@ -3103,16 +3103,18 @@
 ompile(%22
+//
 core:con
@@ -3283,21 +3283,22 @@
 odeList 
-resul
+conten
 ts = (No
@@ -3304,21 +3304,22 @@
 odeList)
-resul
+conten
 tExpr.ev
@@ -3396,21 +3396,22 @@
  i=0; i%3C
-resul
+conten
 ts.getLe
@@ -3523,28 +3523,8 @@
 the 
-content element and 
 uuid
@@ -3588,213 +3588,19 @@
 tent
-Expr.evaluate(results.item(i), XPathConstants.NODE);%0A                if (content == null) %7B%0A                    // Error - content element not found%0A                    break;%0A                %7D else %7B%0A    
+s.item(i);%0A
     
@@ -3689,34 +3689,16 @@
 ent());%0A
-                %7D%0A
         

Fix XML parsing - handle multiple "core:content" elements