/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.xml.security.signature;

import java.io.IOException;
import java.io.OutputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.apache.xml.security.algorithms.Algorithm;
import org.apache.xml.security.algorithms.MessageDigestAlgorithm;
import org.apache.xml.security.c14n.CanonicalizationException;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.signature.reference.ReferenceData;
import org.apache.xml.security.signature.reference.ReferenceNodeSetData;
import org.apache.xml.security.signature.reference.ReferenceOctetStreamData;
import org.apache.xml.security.signature.reference.ReferenceSubTreeData;
import org.apache.xml.security.transforms.InvalidTransformException;
import org.apache.xml.security.transforms.Transform;
import org.apache.xml.security.transforms.TransformationException;
import org.apache.xml.security.transforms.Transforms;
import org.apache.xml.security.transforms.params.InclusiveNamespaces;
import org.apache.xml.security.utils.Constants;
import org.apache.xml.security.utils.DigesterOutputStream;
import org.apache.xml.security.utils.SignatureElementProxy;
import org.apache.xml.security.utils.UnsyncBufferedOutputStream;
import org.apache.xml.security.utils.XMLUtils;
import org.apache.xml.security.utils.resolver.ResourceResolver;
import org.apache.xml.security.utils.resolver.ResourceResolverContext;
import org.apache.xml.security.utils.resolver.ResourceResolverException;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

/**
 * Handles <code>&lt;ds:Reference&gt;</code> elements.
 *
 * This includes:
 *
 * Construct a <CODE>ds:Reference</CODE> from an {@link org.w3c.dom.Element}.
 *
 * <p>Create a new reference</p>
 * <pre>
 * Document doc;
 * MessageDigestAlgorithm sha1 = MessageDigestAlgorithm.getInstance("http://#sha1");
 * Reference ref = new Reference(new XMLSignatureInput(new FileInputStream("1.gif"),
 *                               "http://localhost/1.gif",
 *                               (Transforms) null, sha1);
 * Element refElem = ref.toElement(doc);
 * </pre>
 *
 * <p>Verify a reference</p>
 * <pre>
 * Element refElem = doc.getElement("Reference"); // PSEUDO
 * Reference ref = new Reference(refElem);
 * String url = ref.getURI();
 * ref.setData(new XMLSignatureInput(new FileInputStream(url)));
 * if (ref.verify()) {
 *    System.out.println("verified");
 * }
 * </pre>
 *
 * <pre>
 * &lt;element name="Reference" type="ds:ReferenceType"/&gt;
 *  &lt;complexType name="ReferenceType"&gt;
 *    &lt;sequence&gt;
 *      &lt;element ref="ds:Transforms" minOccurs="0"/&gt;
 *      &lt;element ref="ds:DigestMethod"/&gt;
 *      &lt;element ref="ds:DigestValue"/&gt;
 *    &lt;/sequence&gt;
 *    &lt;attribute name="Id" type="ID" use="optional"/&gt;
 *    &lt;attribute name="URI" type="anyURI" use="optional"/&gt;
 *    &lt;attribute name="Type" type="anyURI" use="optional"/&gt;
 *  &lt;/complexType&gt;
 * </pre>
 *
 * @see ObjectContainer
 * @see Manifest
 */
public class Reference extends SignatureElementProxy {

    /** Field OBJECT_URI */
    public static final String OBJECT_URI = Constants.SignatureSpecNS + Constants._TAG_OBJECT;

    /** Field MANIFEST_URI */
    public static final String MANIFEST_URI = Constants.SignatureSpecNS + Constants._TAG_MANIFEST;

    /**
     * The maximum number of transforms per reference, if secure validation is enabled.
     */
    public static final int MAXIMUM_TRANSFORM_COUNT = 5;

    private boolean secureValidation;

    /**
     * Look up useC14N11 system property. If true, an explicit C14N11 transform
     * will be added if necessary when generating the signature. See section
     * 3.1.1 of http://www.w3.org/2007/xmlsec/Drafts/xmldsig-core/ for more info.
     */
    private static boolean useC14N11 =
        AccessController.doPrivileged((PrivilegedAction<Boolean>)
            () -> Boolean.getBoolean("org.apache.xml.security.useC14N11"));

    private static final org.slf4j.Logger LOG =
        org.slf4j.LoggerFactory.getLogger(Reference.class);

    private Manifest manifest;
    private XMLSignatureInput transformsOutput;

    private Transforms transforms;

    private Element digestMethodElem;

    private Element digestValueElement;

    private ReferenceData referenceData;

    private static final Set<String> TRANSFORM_ALGORITHMS;

    static {
        Set<String> algorithms = new HashSet<>();
        algorithms.add(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS);
        algorithms.add(Transforms.TRANSFORM_C14N_EXCL_WITH_COMMENTS);
        algorithms.add(Transforms.TRANSFORM_C14N_OMIT_COMMENTS);
        algorithms.add(Transforms.TRANSFORM_C14N_WITH_COMMENTS);
        algorithms.add(Transforms.TRANSFORM_C14N11_OMIT_COMMENTS);
        algorithms.add(Transforms.TRANSFORM_C14N11_WITH_COMMENTS);
        TRANSFORM_ALGORITHMS = Collections.unmodifiableSet(algorithms);
    }

    /**
     * Constructor Reference
     *
     * @param doc the {@link Document} in which <code>XMLsignature</code> is placed
     * @param baseURI the URI of the resource where the XML instance will be stored
     * @param referenceURI URI indicate where is data which will digested
     * @param manifest
     * @param transforms {@link Transforms} applied to data
     * @param messageDigestAlgorithm {@link MessageDigestAlgorithm Digest algorithm} which is
     * applied to the data
     * TODO should we throw XMLSignatureException if MessageDigestAlgoURI is wrong?
     */
    protected Reference(
        Document doc, String baseURI, String referenceURI, Manifest manifest,
        Transforms transforms, String messageDigestAlgorithm
    ) throws XMLSignatureException {
        super(doc);

        addReturnToSelf();

        this.baseURI = baseURI;
        this.manifest = manifest;

        this.setURI(referenceURI);

        // important: The ds:Reference must be added to the associated ds:Manifest
        //            or ds:SignedInfo _before_ the this.resolverResult() is called.
        // this.manifest.appendChild(this.constructionElement);
        // this.manifest.appendChild(this.doc.createTextNode("\n"));

        if (transforms != null) {
            this.transforms = transforms;
            appendSelf(transforms);
            addReturnToSelf();
        }

        // Create DigestMethod Element without actually instantiating a MessageDigest Object
        Algorithm digestAlgorithm = new Algorithm(getDocument(), messageDigestAlgorithm) {
            public String getBaseNamespace() {
                return Constants.SignatureSpecNS;
            }

            public String getBaseLocalName() {
                return Constants._TAG_DIGESTMETHOD;
            }
        };

        digestMethodElem = digestAlgorithm.getElement();

        appendSelf(digestMethodElem);
        addReturnToSelf();

        digestValueElement =
            XMLUtils.createElementInSignatureSpace(getDocument(), Constants._TAG_DIGESTVALUE);

        appendSelf(digestValueElement);
        addReturnToSelf();
    }


    /**
     * Build a {@link Reference} from an {@link Element}
     *
     * @param element <code>Reference</code> element
     * @param baseURI the URI of the resource where the XML instance was stored
     * @param manifest is the {@link Manifest} of {@link SignedInfo} in which the Reference occurs.
     * We need this because the Manifest has the individual {@link ResourceResolver}s which have
     * been set by the user
     * @throws XMLSecurityException
     */
    protected Reference(Element element, String baseURI, Manifest manifest) throws XMLSecurityException {
        this(element, baseURI, manifest, true);
    }

    /**
     * Build a {@link Reference} from an {@link Element}
     *
     * @param element <code>Reference</code> element
     * @param baseURI the URI of the resource where the XML instance was stored
     * @param manifest is the {@link Manifest} of {@link SignedInfo} in which the Reference occurs.
     * @param secureValidation whether secure validation is enabled or not
     * We need this because the Manifest has the individual {@link ResourceResolver}s which have
     * been set by the user
     * @throws XMLSecurityException
     */
    protected Reference(Element element, String baseURI, Manifest manifest, boolean secureValidation)
        throws XMLSecurityException {
        super(element, baseURI);
        this.secureValidation = secureValidation;
        this.baseURI = baseURI;
        Element el = XMLUtils.getNextElement(element.getFirstChild());

        if (el != null && Constants._TAG_TRANSFORMS.equals(el.getLocalName())
            && Constants.SignatureSpecNS.equals(el.getNamespaceURI())) {
            transforms = new Transforms(el, this.baseURI);
            transforms.setSecureValidation(secureValidation);
            if (secureValidation && transforms.getLength() > MAXIMUM_TRANSFORM_COUNT) {
                Object[] exArgs = { transforms.getLength(), MAXIMUM_TRANSFORM_COUNT };

                throw new XMLSecurityException("signature.tooManyTransforms", exArgs);
            }
            el = XMLUtils.getNextElement(el.getNextSibling());
        }

        digestMethodElem = el;
        if (digestMethodElem == null ||
            !(Constants.SignatureSpecNS.equals(digestMethodElem.getNamespaceURI())
                && Constants._TAG_DIGESTMETHOD.equals(digestMethodElem.getLocalName()))) {
            throw new XMLSecurityException("signature.Reference.NoDigestMethod");
        }

        digestValueElement = XMLUtils.getNextElement(digestMethodElem.getNextSibling());
        if (digestValueElement == null ||
            !(Constants.SignatureSpecNS.equals(digestValueElement.getNamespaceURI())
                && Constants._TAG_DIGESTVALUE.equals(digestValueElement.getLocalName()))) {
            throw new XMLSecurityException("signature.Reference.NoDigestValue");
        }
        this.manifest = manifest;
    }

    /**
     * Returns {@link MessageDigestAlgorithm}
     *
     *
     * @return {@link MessageDigestAlgorithm}
     *
     * @throws XMLSignatureException
     */
    public MessageDigestAlgorithm getMessageDigestAlgorithm() throws XMLSignatureException {
        if (digestMethodElem == null) {
            return null;
        }

        String uri = digestMethodElem.getAttributeNS(null, Constants._ATT_ALGORITHM);

        if (uri.isEmpty()) {
            return null;
        }

        if (secureValidation && MessageDigestAlgorithm.ALGO_ID_DIGEST_NOT_RECOMMENDED_MD5.equals(uri)) {
            Object[] exArgs = { uri };

            throw new XMLSignatureException("signature.signatureAlgorithm", exArgs);
        }

        return MessageDigestAlgorithm.getInstance(getDocument(), uri);
    }

    /**
     * Sets the <code>URI</code> of this <code>Reference</code> element
     *
     * @param uri the <code>URI</code> of this <code>Reference</code> element
     */
    public void setURI(String uri) {
        if (uri != null) {
            setLocalAttribute(Constants._ATT_URI, uri);
        }
    }

    /**
     * Returns the <code>URI</code> of this <code>Reference</code> element
     *
     * @return URI the <code>URI</code> of this <code>Reference</code> element
     */
    public String getURI() {
        return getLocalAttribute(Constants._ATT_URI);
    }

    /**
     * Sets the <code>Id</code> attribute of this <code>Reference</code> element
     *
     * @param id the <code>Id</code> attribute of this <code>Reference</code> element
     */
    public void setId(String id) {
        if (id != null) {
            setLocalIdAttribute(Constants._ATT_ID, id);
        }
    }

    /**
     * Returns the <code>Id</code> attribute of this <code>Reference</code> element
     *
     * @return Id the <code>Id</code> attribute of this <code>Reference</code> element
     */
    public String getId() {
        return getLocalAttribute(Constants._ATT_ID);
    }

    /**
     * Sets the <code>type</code> atttibute of the Reference indicate whether an
     * <code>ds:Object</code>, <code>ds:SignatureProperty</code>, or <code>ds:Manifest</code>
     * element.
     *
     * @param type the <code>type</code> attribute of the Reference
     */
    public void setType(String type) {
        if (type != null) {
            setLocalAttribute(Constants._ATT_TYPE, type);
        }
    }

    /**
     * Return the <code>type</code> attribute of the Reference indicate whether an
     * <code>ds:Object</code>, <code>ds:SignatureProperty</code>, or <code>ds:Manifest</code>
     * element
     *
     * @return the <code>type</code> attribute of the Reference
     */
    public String getType() {
        return getLocalAttribute(Constants._ATT_TYPE);
    }

    /**
     * Method isReferenceToObject
     *
     * This returns true if the <CODE>Type</CODE> attribute of the
     * <CODE>Reference</CODE> element points to a <CODE>#Object</CODE> element
     *
     * @return true if the Reference type indicates that this Reference points to an
     * <code>Object</code>
     */
    public boolean typeIsReferenceToObject() {
        return Reference.OBJECT_URI.equals(this.getType());
    }

    /**
     * Method isReferenceToManifest
     *
     * This returns true if the <CODE>Type</CODE> attribute of the
     * <CODE>Reference</CODE> element points to a <CODE>#Manifest</CODE> element
     *
     * @return true if the Reference type indicates that this Reference points to a
     * {@link Manifest}
     */
    public boolean typeIsReferenceToManifest() {
        return Reference.MANIFEST_URI.equals(this.getType());
    }

    /**
     * Method setDigestValueElement
     *
     * @param digestValue
     */
    private void setDigestValueElement(byte[] digestValue) {
        Node n = digestValueElement.getFirstChild();
        while (n != null) {
            digestValueElement.removeChild(n);
            n = n.getNextSibling();
        }

        String base64codedValue = XMLUtils.encodeToString(digestValue);
        Text t = createText(base64codedValue);

        digestValueElement.appendChild(t);
    }

    /**
     * Method generateDigestValue
     *
     * @throws ReferenceNotInitializedException
     * @throws XMLSignatureException
     */
    public void generateDigestValue()
        throws XMLSignatureException, ReferenceNotInitializedException {
        this.setDigestValueElement(this.calculateDigest(false));
    }

    /**
     * Returns the XMLSignatureInput which is created by de-referencing the URI attribute.
     * @return the XMLSignatureInput of the source of this reference
     * @throws ReferenceNotInitializedException If the resolver found any
     * problem resolving the reference
     */
    public XMLSignatureInput getContentsBeforeTransformation()
        throws ReferenceNotInitializedException {
        try {
            Attr uriAttr =
                getElement().getAttributeNodeNS(null, Constants._ATT_URI);

            ResourceResolverContext resolverContext =
                new ResourceResolverContext(uriAttr, this.baseURI,
                    secureValidation, this.manifest.getResolverProperties());

            return ResourceResolver.resolve(this.manifest.getPerManifestResolvers(), resolverContext);
        }  catch (ResourceResolverException ex) {
            throw new ReferenceNotInitializedException(ex);
        }
    }

    private XMLSignatureInput getContentsAfterTransformation(
        XMLSignatureInput input, OutputStream os
    ) throws XMLSignatureException {
        try {
            Transforms transforms = this.getTransforms();
            XMLSignatureInput output = null;

            if (transforms != null) {
                output = transforms.performTransforms(input, os);
                this.transformsOutput = output;//new XMLSignatureInput(output.getBytes());

                //this.transformsOutput.setSourceURI(output.getSourceURI());
            } else {
                output = input;
            }

            return output;
        } catch (XMLSecurityException ex) {
            throw new XMLSignatureException(ex);
        }
    }

    /**
     * Returns the XMLSignatureInput which is the result of the Transforms.
     * @return a XMLSignatureInput with all transformations applied.
     * @throws XMLSignatureException
     */
    public XMLSignatureInput getContentsAfterTransformation()
        throws XMLSignatureException {
        XMLSignatureInput input = this.getContentsBeforeTransformation();
        cacheDereferencedElement(input);

        return this.getContentsAfterTransformation(input, null);
    }

    /**
     * This method returns the XMLSignatureInput which represents the node set before
     * some kind of canonicalization is applied for the first time.
     * @return Gets a the node doing everything till the first c14n is needed
     *
     * @throws XMLSignatureException
     */
    public XMLSignatureInput getNodesetBeforeFirstCanonicalization()
        throws XMLSignatureException {
        try {
            XMLSignatureInput input = this.getContentsBeforeTransformation();
            cacheDereferencedElement(input);
            XMLSignatureInput output = input;
            Transforms transforms = this.getTransforms();

            if (transforms != null) {
                for (int i = 0; i < transforms.getLength(); i++) {
                    Transform t = transforms.item(i);
                    String uri = t.getURI();

                    if (TRANSFORM_ALGORITHMS.contains(uri)) {
                        break;
                    }

                    output = t.performTransform(output, null, secureValidation);
                }

                output.setSourceURI(input.getSourceURI());
            }
            return output;
        } catch (IOException | XMLSecurityException ex) {
            throw new XMLSignatureException(ex);
        }
    }

    /**
     * Method getHTMLRepresentation
     * @return The HTML of the transformation
     * @throws XMLSignatureException
     */
    public String getHTMLRepresentation() throws XMLSignatureException {
        try {
            XMLSignatureInput nodes = this.getNodesetBeforeFirstCanonicalization();

            Transforms transforms = this.getTransforms();
            Transform c14nTransform = null;

            if (transforms != null) {
                for (int i = 0; i < transforms.getLength(); i++) {
                    Transform t = transforms.item(i);
                    String uri = t.getURI();

                    if (uri.equals(Transforms.TRANSFORM_C14N_EXCL_OMIT_COMMENTS)
                        || uri.equals(Transforms.TRANSFORM_C14N_EXCL_WITH_COMMENTS)) {
                        c14nTransform = t;
                        break;
                    }
                }
            }

            Set<String> inclusiveNamespaces = new HashSet<>();
            if (c14nTransform != null
                && c14nTransform.length(
                    InclusiveNamespaces.ExclusiveCanonicalizationNamespace,
                    InclusiveNamespaces._TAG_EC_INCLUSIVENAMESPACES) == 1) {

                // there is one InclusiveNamespaces element
                InclusiveNamespaces in =
                    new InclusiveNamespaces(
                        XMLUtils.selectNode(
                            c14nTransform.getElement().getFirstChild(),
                            InclusiveNamespaces.ExclusiveCanonicalizationNamespace,
                            InclusiveNamespaces._TAG_EC_INCLUSIVENAMESPACES,
                            0
                        ), this.getBaseURI());

                inclusiveNamespaces =
                    InclusiveNamespaces.prefixStr2Set(in.getInclusiveNamespaces());
            }

            return nodes.getHTMLRepresentation(inclusiveNamespaces);
        } catch (XMLSecurityException ex) {
            throw new XMLSignatureException(ex);
        }
    }

    /**
     * This method only works after a call to verify.
     * @return the transformed output(i.e. what is going to be digested).
     */
    public XMLSignatureInput getTransformsOutput() {
        return this.transformsOutput;
    }

    /**
     * Get the ReferenceData that corresponds to the cached representation of the dereferenced
     * object before transformation.
     */
    public ReferenceData getReferenceData() {
        return referenceData;
    }

    /**
     * This method returns the {@link XMLSignatureInput} which is referenced by the
     * <CODE>URI</CODE> Attribute.
     * @param os where to write the transformation can be null.
     * @return the element to digest
     *
     * @throws XMLSignatureException
     * @see Manifest#verifyReferences()
     */
    protected XMLSignatureInput dereferenceURIandPerformTransforms(OutputStream os)
        throws XMLSignatureException {
        try {
            XMLSignatureInput input = this.getContentsBeforeTransformation();
            cacheDereferencedElement(input);

            XMLSignatureInput output = this.getContentsAfterTransformation(input, os);
            this.transformsOutput = output;
            return output;
        } catch (XMLSecurityException ex) {
            throw new ReferenceNotInitializedException(ex);
        }
    }

    /**
     * Store the dereferenced Element(s) so that it/they can be retrieved later.
     */
    private void cacheDereferencedElement(XMLSignatureInput input) {
        if (input.isNodeSet()) {
            try {
                final Set<Node> s = input.getNodeSet();
                referenceData = new ReferenceNodeSetData() {
                    public Iterator<Node> iterator() {
                        return new Iterator<Node>() {

                            final Iterator<Node> sIterator = s.iterator();

                            @Override
                            public boolean hasNext() {
                                return sIterator.hasNext();
                            }

                            @Override
                            public Node next() {
                                return sIterator.next();
                            }

                            @Override
                            public void remove() {
                                throw new UnsupportedOperationException();
                            }
                        };
                    }
                };
            } catch (Exception e) {
                // LOG a warning
                LOG.warn("cannot cache dereferenced data: " + e);
            }
        } else if (input.isElement()) {
            referenceData = new ReferenceSubTreeData
                (input.getSubNode(), input.isExcludeComments());
        } else if (input.isOctetStream() || input.isByteArray()) {
            try {
                referenceData = new ReferenceOctetStreamData
                    (input.getOctetStream(), input.getSourceURI(),
                        input.getMIMEType());
            } catch (IOException ioe) {
                // LOG a warning
                LOG.warn("cannot cache dereferenced data: " + ioe);
            }
        }
    }

    /**
     * Method getTransforms
     *
     * @return The transforms that applied this reference.
     * @throws InvalidTransformException
     * @throws TransformationException
     * @throws XMLSecurityException
     * @throws XMLSignatureException
     */
    public Transforms getTransforms()
        throws XMLSignatureException, InvalidTransformException,
        TransformationException, XMLSecurityException {
        return transforms;
    }

    /**
     * Method getReferencedBytes
     *
     * @return the bytes that will be used to generated digest.
     * @throws ReferenceNotInitializedException
     * @throws XMLSignatureException
     */
    public byte[] getReferencedBytes()
        throws ReferenceNotInitializedException, XMLSignatureException {
        try {
            XMLSignatureInput output = this.dereferenceURIandPerformTransforms(null);
            return output.getBytes();
        } catch (IOException | CanonicalizationException ex) {
            throw new ReferenceNotInitializedException(ex);
        }
    }


    /**
     * Method calculateDigest
     *
     * @param validating true if validating the reference
     * @return reference Calculate the digest of this reference.
     * @throws ReferenceNotInitializedException
     * @throws XMLSignatureException
     */
    private byte[] calculateDigest(boolean validating)
        throws ReferenceNotInitializedException, XMLSignatureException {
        XMLSignatureInput input = this.getContentsBeforeTransformation();
        if (input.isPreCalculatedDigest()) {
            return getPreCalculatedDigest(input);
        }

        cacheDereferencedElement(input);

        MessageDigestAlgorithm mda = this.getMessageDigestAlgorithm();
        mda.reset();

        try (DigesterOutputStream diOs = new DigesterOutputStream(mda);
            OutputStream os = new UnsyncBufferedOutputStream(diOs)) {

            XMLSignatureInput output = this.getContentsAfterTransformation(input, os);
            this.transformsOutput = output;

            // if signing and c14n11 property == true explicitly add
            // C14N11 transform if needed
            if (Reference.useC14N11 && !validating && !output.isOutputStreamSet()
                && !output.isOctetStream()) {
                if (transforms == null) {
                    transforms = new Transforms(getDocument());
                    transforms.setSecureValidation(secureValidation);
                    getElement().insertBefore(transforms.getElement(), digestMethodElem);
                }
                transforms.addTransform(Transforms.TRANSFORM_C14N11_OMIT_COMMENTS);
                output.updateOutputStream(os, true);
            } else {
                output.updateOutputStream(os);
            }
            os.flush();

            if (output.getOctetStreamReal() != null) {
                output.getOctetStreamReal().close();
            }

            //this.getReferencedBytes(diOs);
            //mda.update(data);

            return diOs.getDigestValue();
        } catch (XMLSecurityException | IOException ex) {
            throw new ReferenceNotInitializedException(ex);
        }
    }

    /**
     * Get the pre-calculated digest value from the XMLSignatureInput.
     *
     * @param input XMLSignature
     * @return a pre-calculated digest value.
     * @throws ReferenceNotInitializedException if there is an error decoding digest value
     * in Base64. Properly encoded pre-calculated digest value must be set.
     */
    private byte[] getPreCalculatedDigest(XMLSignatureInput input)
            throws ReferenceNotInitializedException {
        LOG.debug("Verifying element with pre-calculated digest");
        String preCalculatedDigest = input.getPreCalculatedDigest();
        return XMLUtils.decode(preCalculatedDigest);
    }

    /**
     * Returns the digest value.
     *
     * @return the digest value.
     * @throws XMLSecurityException if the Reference does not contain a DigestValue element
     */
    public byte[] getDigestValue() throws XMLSecurityException {
        if (digestValueElement == null) {
            // The required element is not in the XML!
            Object[] exArgs ={ Constants._TAG_DIGESTVALUE, Constants.SignatureSpecNS };
            throw new XMLSecurityException(
                "signature.Verification.NoSignatureElement", exArgs
            );
        }
        String content = XMLUtils.getFullTextChildrenFromNode(digestValueElement);
        return XMLUtils.decode(content);
    }


    /**
     * Tests reference validation is success or false
     *
     * @return true if reference validation is success, otherwise false
     * @throws ReferenceNotInitializedException
     * @throws XMLSecurityException
     */
    public boolean verify()
        throws ReferenceNotInitializedException, XMLSecurityException {
        byte[] elemDig = this.getDigestValue();
        byte[] calcDig = this.calculateDigest(true);
        boolean equal = MessageDigestAlgorithm.isEqual(elemDig, calcDig);

        if (!equal) {
            LOG.warn("Verification failed for URI \"" + this.getURI() + "\"");
            LOG.warn("Expected Digest: " + XMLUtils.encodeToString(elemDig));
            LOG.warn("Actual Digest: " + XMLUtils.encodeToString(calcDig));
        } else {
            LOG.debug("Verification successful for URI \"{}\"", this.getURI());
        }

        return equal;
    }

    /**
     * Method getBaseLocalName
     * {@inheritDoc}
     */
    public String getBaseLocalName() {
        return Constants._TAG_REFERENCE;
    }
}
