/**
 * 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.test.dom.signature;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.apache.xml.security.signature.XMLSignatureInput;
import org.apache.xml.security.test.dom.DSNamespaceContext;
import org.apache.xml.security.utils.resolver.ResourceResolverContext;
import org.apache.xml.security.utils.resolver.ResourceResolverException;
import org.apache.xml.security.utils.resolver.ResourceResolverSpi;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * An implementation of a resource resolver, which evaluates xpointer expressions.
 *
 */
public class XPointerResourceResolver extends ResourceResolverSpi {
    private static final org.slf4j.Logger LOG =
        org.slf4j.LoggerFactory.getLogger(XPointerResourceResolver.class);

    private static final String XP_OPEN = "xpointer(";
    private static final String XNS_OPEN = "xmlns(";

    private Node baseNode;

    public XPointerResourceResolver(Node baseNode) {
        this.baseNode = baseNode;
    }

    @Override
    public boolean engineCanResolveURI(ResourceResolverContext context) {
        String v = context.uriToResolve;

        if (v == null || v.length() <= 0) {
            return false;
        }

        if (v.charAt(0) != '#') {
            return false;
        }

        String xpURI;
        try {
            xpURI = URLDecoder.decode(v, "utf-8");
        } catch (UnsupportedEncodingException e) {
            LOG.warn("utf-8 not a valid encoding",e);
            return false;
        }

        String parts[] = xpURI.substring(1).split("\\s");

        // plain ID reference.
        if (parts.length == 1 && !parts[0].startsWith(XNS_OPEN)) {
            return true;
        }

        int i = 0;
        for (; i < parts.length - 1; ++i) {
            if (!parts[i].endsWith(")") ||  !parts[i].startsWith(XNS_OPEN)) {
                return false;
            }
        }

        if (!parts[i].endsWith(")") || !parts[i].startsWith(XP_OPEN)) {
            return false;
        }

        LOG.debug("xpURI = " + xpURI);
        LOG.debug("BaseURI = " + context.baseUri);

        return true;
    }

    @Override
    public XMLSignatureInput engineResolveURI(ResourceResolverContext context)
        throws ResourceResolverException {
        String v = context.uriToResolve;

        if (v.charAt(0) != '#') {
            return null;
        }

        String xpURI;
        try {
            xpURI = URLDecoder.decode(v, "utf-8");
        } catch (UnsupportedEncodingException e) {
            LOG.warn("utf-8 not a valid encoding ", e);
            return null;
        }

        String parts[] = xpURI.substring(1).split("\\s");

        int i = 0;
        Map<String, String> namespaces = new HashMap<>();

        if (parts.length > 1) {

            for (; i < parts.length - 1; ++i) {
                if (!parts[i].endsWith(")") ||  !parts[i].startsWith(XNS_OPEN)) {
                    return null;
                }

                String mapping = parts[i].substring(XNS_OPEN.length(), parts[i].length() - 1);

                int pos = mapping.indexOf('=');

                if (pos <= 0 || pos >= mapping.length() - 1) {
                    throw new ResourceResolverException(
                        "malformed namespace part of XPointer expression", context.uriToResolve, context.baseUri
                    );
                }

                namespaces.put(
                    mapping.substring(0, pos),
                    mapping.substring(pos + 1)
                );
            }
        }

        try {
            Node node = null;
            NodeList nodes = null;

            // plain ID reference.
            if (i == 0 && !parts[i].startsWith(XP_OPEN)) {
                node = this.baseNode.getOwnerDocument().getElementById(parts[i]);
            } else {
                if (!parts[i].endsWith(")") || !parts[i].startsWith(XP_OPEN)) {
                    return null;
                }

                String xpathExpr = parts[i].substring(XP_OPEN.length(), parts[i].length() - 1);

                XPathFactory xpf = XPathFactory.newInstance();
                XPath xpath = xpf.newXPath();
                DSNamespaceContext namespaceContext =
                    new DSNamespaceContext(namespaces);
                xpath.setNamespaceContext(namespaceContext);

                nodes =
                    (NodeList) xpath.evaluate(
                        xpathExpr, this.baseNode, XPathConstants.NODESET
                    );

                if (nodes.getLength() == 0) {
                    return null;
                }
                if (nodes.getLength() == 1) {
                    node = nodes.item(0);
                }
            }

            XMLSignatureInput result = null;

            if (node != null) {
                result = new XMLSignatureInput(node);
            } else if (nodes != null) {
                Set<Node> nodeSet = new HashSet<>(nodes.getLength());

                for (int j = 0; j < nodes.getLength(); ++j) {
                    nodeSet.add(nodes.item(j));
                }

                result = new XMLSignatureInput(nodeSet);
            } else {
                return null;
            }

            result.setMIMEType("text/xml");
            result.setExcludeComments(true);
            result.setSourceURI((context.baseUri != null) ? context.baseUri.concat(v) : v);

            return result;
        } catch (XPathExpressionException e) {
            throw new ResourceResolverException(
                 e, context.uriToResolve, context.baseUri, "Problem evaluating XPath expression"
            );
        }
    }

}
