package org.datacite.mds.validation.constraints.impl;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.lang.StringUtils;
import org.datacite.mds.domain.Metadata;
import org.datacite.mds.util.ValidationUtils;
import org.datacite.mds.validation.constraints.MatchDoi;
import org.xml.sax.InputSource;

public class MatchDoiValidator implements ConstraintValidator<MatchDoi, Metadata> {
    String defaultMessage;

    XPathExpression xPathExpression;
    String xPath = "//identifier[@identifierType='DOI']";
    
    
    public void initialize(MatchDoi constraintAnnotation) {
        defaultMessage = constraintAnnotation.message();
        initXPath();
    }
    
    private void initXPath() {
        XPathFactory factory = XPathFactory.newInstance(); 
        XPath xPath = factory.newXPath();
        try {
            xPathExpression = xPath.compile(this.xPath);
        } catch (XPathExpressionException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public boolean isValid(Metadata metadata, ConstraintValidatorContext context) {
        ValidationUtils.addConstraintViolation(context, defaultMessage, "xml");
        String doiFromDataset = metadata.getDataset().getDoi();
        String doiFromXml;
        try {
            doiFromXml = getDoiFromXml(metadata);
        } catch (XPathExpressionException e) {
            return false;
        }
        System.out.println(metadata.getDataset());
        System.out.println(doiFromDataset + " ?= " + doiFromXml);
        boolean isValid = StringUtils.equals(doiFromDataset, doiFromXml); 
        return isValid;
    }
    
    private String getDoiFromXml(Metadata metadata) throws XPathExpressionException  {
        byte[] xml = metadata.getXml();
        InputStream stream = new ByteArrayInputStream(xml);
        InputSource source = new InputSource(stream); 
        String doi = xPathExpression.evaluate(source);
        return doi;
    }
}

@@ -453,16 +453,52 @@
 tadata;%0A
+import org.datacite.mds.util.Utils;%0A
 import o
@@ -832,25 +832,16 @@
 DOI'%5D%22;%0A
-    %0A    
 %0A    pub
@@ -969,36 +969,32 @@
 tXPath();%0A    %7D%0A
-    
 %0A    private voi
@@ -1067,17 +1067,16 @@
 tance();
- 
 %0A       
@@ -1621,16 +1621,73 @@
 adata);%0A
+            doiFromXml = Utils.normalizeDoi(doiFromXml);%0A
         
@@ -1765,125 +1765,8 @@
   %7D%0A
-        System.out.println(metadata.getDataset());%0A        System.out.println(doiFromDataset + %22 ?= %22 + doiFromXml);%0A
     
@@ -1834,17 +1834,16 @@
 romXml);
- 
 %0A       
@@ -1865,20 +1865,16 @@
 ;%0A    %7D%0A
-    
 %0A    pri
@@ -1950,17 +1950,16 @@
 ception 
- 
 %7B%0A      
@@ -2105,17 +2105,16 @@
 stream);
- 
 %0A       

normalize doi before comparison