/**
 * 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.utils.resolver.implementations;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.URISyntaxException;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Map;

import org.apache.xml.security.signature.XMLSignatureInput;
import org.apache.xml.security.utils.XMLUtils;
import org.apache.xml.security.utils.resolver.ResourceResolverContext;
import org.apache.xml.security.utils.resolver.ResourceResolverException;
import org.apache.xml.security.utils.resolver.ResourceResolverSpi;

/**
 * A simple ResourceResolver for HTTP requests. This class handles only 'pure'
 * HTTP URIs which means without a fragment. The Fragment handling is done by the
 * {@link ResolverFragment} class.
 * <BR>
 * If the user has a corporate HTTP proxy which is to be used, the usage can be
 * switched on by setting properties for the resolver:
 * <PRE>
 * resourceResolver.setProperty("http.proxy.host", "proxy.company.com");
 * resourceResolver.setProperty("http.proxy.port", "8080");
 *
 * // if we need a password for the proxy
 * resourceResolver.setProperty("http.proxy.username", "proxyuser3");
 * resourceResolver.setProperty("http.proxy.password", "secretca");
 * </PRE>
 *
 * @see <A HREF="http://www.javaworld.com/javaworld/javatips/jw-javatip42_p.html">Java Tip 42: Write Java apps that work with proxy-based firewalls</A>
 * @see <A HREF="https://docs.oracle.com/javase/8/docs/technotes/guides/net/properties.html">JDK docs for network properties</A>
 * @see <A HREF="http://metalab.unc.edu/javafaq/javafaq.html#proxy">The JAVA FAQ Question 9.5: How do I make Java work with a proxy server?</A>
 */
public class ResolverDirectHTTP extends ResourceResolverSpi {

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

    /** Field properties[] */
    private static final String[] properties = {
                                                 "http.proxy.host", "http.proxy.port",
                                                 "http.proxy.username", "http.proxy.password",
                                                 "http.basic.username", "http.basic.password"
                                               };

    /** Field HttpProxyHost */
    private static final int HttpProxyHost = 0;

    /** Field HttpProxyPort */
    private static final int HttpProxyPort = 1;

    /** Field HttpProxyUser */
    private static final int HttpProxyUser = 2;

    /** Field HttpProxyPass */
    private static final int HttpProxyPass = 3;

    /** Field HttpProxyUser */
    private static final int HttpBasicUser = 4;

    /** Field HttpProxyPass */
    private static final int HttpBasicPass = 5;

    private final Map<String, String> resolverProperties;

    public ResolverDirectHTTP() {
        resolverProperties = Collections.emptyMap();
    }

    public ResolverDirectHTTP(Map<String, String> resolverProperties) {
        this.resolverProperties =
            Collections.unmodifiableMap(resolverProperties != null ? resolverProperties : Collections.emptyMap());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public XMLSignatureInput engineResolveURI(ResourceResolverContext context)
        throws ResourceResolverException {

        try {
            // calculate new URI
            URI uriNew = getNewURI(context.uriToResolve, context.baseUri);
            URL url = uriNew.toURL();
            URLConnection urlConnection = openConnection(url, context);

            // check if Basic authentication is required
            String auth = urlConnection.getHeaderField("WWW-Authenticate");

            if (auth != null && auth.startsWith("Basic")) {
                // do http basic authentication
                String user =
                    getProperty(context, ResolverDirectHTTP.properties[ResolverDirectHTTP.HttpBasicUser]);
                String pass =
                    getProperty(context, ResolverDirectHTTP.properties[ResolverDirectHTTP.HttpBasicPass]);

                if (user != null && pass != null) {
                    urlConnection = openConnection(url, context);

                    String password = user + ":" + pass;
                    String encodedPassword = XMLUtils.encodeToString(password.getBytes(StandardCharsets.ISO_8859_1));

                    // set authentication property in the http header
                    urlConnection.setRequestProperty("Authorization",
                                                     "Basic " + encodedPassword);
                }
            }

            String mimeType = urlConnection.getHeaderField("Content-Type");
            try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
                InputStream inputStream = urlConnection.getInputStream()) {
                byte[] buf = new byte[4096];
                int read = 0;
                int summarized = 0;

                while ((read = inputStream.read(buf)) >= 0) {
                    baos.write(buf, 0, read);
                    summarized += read;
                }

                LOG.debug("Fetched {} bytes from URI {}", summarized, uriNew.toString());

                XMLSignatureInput result = new XMLSignatureInput(baos.toByteArray());
                result.setSecureValidation(context.secureValidation);

                result.setSourceURI(uriNew.toString());
                result.setMIMEType(mimeType);

                return result;
            }

        } catch (URISyntaxException ex) {
            throw new ResourceResolverException(ex, context.uriToResolve, context.baseUri, "generic.EmptyMessage");
        } catch (MalformedURLException ex) {
            throw new ResourceResolverException(ex, context.uriToResolve, context.baseUri, "generic.EmptyMessage");
        } catch (IOException ex) {
            throw new ResourceResolverException(ex, context.uriToResolve, context.baseUri, "generic.EmptyMessage");
        } catch (IllegalArgumentException e) {
            throw new ResourceResolverException(e, context.uriToResolve, context.baseUri, "generic.EmptyMessage");
        }
    }

    private URLConnection openConnection(URL url, ResourceResolverContext context) throws IOException {

        String proxyHostProp =
            getProperty(context, ResolverDirectHTTP.properties[ResolverDirectHTTP.HttpProxyHost]);
        String proxyPortProp =
            getProperty(context, ResolverDirectHTTP.properties[ResolverDirectHTTP.HttpProxyPort]);
        String proxyUser =
            getProperty(context, ResolverDirectHTTP.properties[ResolverDirectHTTP.HttpProxyUser]);
        String proxyPass =
            getProperty(context, ResolverDirectHTTP.properties[ResolverDirectHTTP.HttpProxyPass]);

        Proxy proxy = null;
        if (proxyHostProp != null && proxyPortProp != null) {
            int port = Integer.parseInt(proxyPortProp);
            proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHostProp, port));
        }

        URLConnection urlConnection;
        if (proxy != null) {
            urlConnection = url.openConnection(proxy);

            if (proxyUser != null && proxyPass != null) {
                String password = proxyUser + ":" + proxyPass;
                String authString = "Basic " + XMLUtils.encodeToString(password.getBytes(StandardCharsets.ISO_8859_1));

                urlConnection.setRequestProperty("Proxy-Authorization", authString);
            }
        } else {
            urlConnection = url.openConnection();
        }

        return urlConnection;
    }

    /**
     * We resolve http URIs <I>without</I> fragment...
     *
     * @param context
     * @return true if can be resolved
     */
    public boolean engineCanResolveURI(ResourceResolverContext context) {
        if (context.uriToResolve == null) {
            LOG.debug("quick fail, uri == null");
            return false;
        }

        if (context.uriToResolve.isEmpty() || context.uriToResolve.charAt(0) == '#') {
            LOG.debug("quick fail for empty URIs and local ones");
            return false;
        }

        LOG.debug("I was asked whether I can resolve {}", context.uriToResolve);

        if (context.uriToResolve.startsWith("http:") ||
            context.baseUri != null && context.baseUri.startsWith("http:")) {
            LOG.debug("I state that I can resolve {}", context.uriToResolve);
            return true;
        }

        LOG.debug("I state that I can't resolve {}", context.uriToResolve);

        return false;
    }

    private static URI getNewURI(String uri, String baseURI) throws URISyntaxException {
        URI newUri = null;
        if (baseURI == null || "".equals(baseURI)) {
            newUri = new URI(uri);
        } else {
            newUri = new URI(baseURI).resolve(uri);
        }

        // if the URI contains a fragment, ignore it
        if (newUri.getFragment() != null) {
            URI uriNewNoFrag =
                new URI(newUri.getScheme(), newUri.getSchemeSpecificPart(), null);
            return uriNewNoFrag;
        }
        return newUri;
    }

    private String getProperty(ResourceResolverContext context, String propertyName) {
        // First check the properties defined on this Resolver.
        if (resolverProperties.containsKey(propertyName)) {
            return resolverProperties.get(propertyName);
        }

        // Otherwise defer to the passed in properties
        return context.getProperties().get(propertyName);
    }

}
