// 
// Decompiled by Procyon v0.6.0
// 

package com.nimbusds.jose.util;

import java.io.InputStream;
import java.util.Iterator;
import java.net.URLConnection;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.net.HttpURLConnection;
import javax.net.ssl.HttpsURLConnection;
import java.net.URL;
import java.net.Proxy;
import javax.net.ssl.SSLSocketFactory;
import com.nimbusds.jose.shaded.jcip.ThreadSafe;

@ThreadSafe
public class DefaultResourceRetriever extends AbstractRestrictedResourceRetriever implements RestrictedResourceRetriever
{
    private boolean disconnectAfterUse;
    private final SSLSocketFactory sslSocketFactory;
    private Proxy proxy;
    
    public DefaultResourceRetriever() {
        this(0, 0);
    }
    
    public DefaultResourceRetriever(final int connectTimeout, final int readTimeout) {
        this(connectTimeout, readTimeout, 0);
    }
    
    public DefaultResourceRetriever(final int connectTimeout, final int readTimeout, final int sizeLimit) {
        this(connectTimeout, readTimeout, sizeLimit, true);
    }
    
    public DefaultResourceRetriever(final int connectTimeout, final int readTimeout, final int sizeLimit, final boolean disconnectAfterUse) {
        this(connectTimeout, readTimeout, sizeLimit, disconnectAfterUse, null);
    }
    
    public DefaultResourceRetriever(final int connectTimeout, final int readTimeout, final int sizeLimit, final boolean disconnectAfterUse, final SSLSocketFactory sslSocketFactory) {
        super(connectTimeout, readTimeout, sizeLimit);
        this.disconnectAfterUse = disconnectAfterUse;
        this.sslSocketFactory = sslSocketFactory;
    }
    
    public boolean disconnectsAfterUse() {
        return this.disconnectAfterUse;
    }
    
    public void setDisconnectsAfterUse(final boolean disconnectAfterUse) {
        this.disconnectAfterUse = disconnectAfterUse;
    }
    
    public Proxy getProxy() {
        return this.proxy;
    }
    
    public void setProxy(final Proxy proxy) {
        this.proxy = proxy;
    }
    
    @Override
    public Resource retrieveResource(final URL url) throws IOException {
        URLConnection con = null;
        try {
            if ("file".equals(url.getProtocol())) {
                con = this.openFileConnection(url);
            }
            else {
                con = this.openConnection(url);
            }
            con.setConnectTimeout(this.getConnectTimeout());
            con.setReadTimeout(this.getReadTimeout());
            if (con instanceof HttpsURLConnection && this.sslSocketFactory != null) {
                ((HttpsURLConnection)con).setSSLSocketFactory(this.sslSocketFactory);
            }
            if (con instanceof HttpURLConnection && this.getHeaders() != null && !this.getHeaders().isEmpty()) {
                for (final Map.Entry<String, List<String>> entry : this.getHeaders().entrySet()) {
                    for (final String value : entry.getValue()) {
                        con.addRequestProperty(entry.getKey(), value);
                    }
                }
            }
            String content;
            try (final InputStream inputStream = this.getInputStream(con, this.getSizeLimit())) {
                content = IOUtils.readInputStreamToString(inputStream, StandardCharset.UTF_8);
            }
            if (con instanceof HttpURLConnection) {
                final HttpURLConnection httpCon = (HttpURLConnection)con;
                final int statusCode = httpCon.getResponseCode();
                final String statusMessage = httpCon.getResponseMessage();
                if (statusCode > 299 || statusCode < 200) {
                    throw new IOException("HTTP " + statusCode + ": " + statusMessage);
                }
            }
            final String contentType = (con instanceof HttpURLConnection) ? con.getContentType() : null;
            return new Resource(content, contentType);
        }
        catch (final Exception e) {
            if (e instanceof IOException) {
                throw e;
            }
            throw new IOException("Couldn't open URL connection: " + e.getMessage(), e);
        }
        finally {
            if (this.disconnectAfterUse && con instanceof HttpURLConnection) {
                ((HttpURLConnection)con).disconnect();
            }
        }
    }
    
    @Deprecated
    protected HttpURLConnection openConnection(final URL url) throws IOException {
        return this.openHTTPConnection(url);
    }
    
    protected HttpURLConnection openHTTPConnection(final URL url) throws IOException {
        if (this.proxy != null) {
            return (HttpURLConnection)url.openConnection(this.proxy);
        }
        return (HttpURLConnection)url.openConnection();
    }
    
    protected URLConnection openFileConnection(final URL url) throws IOException {
        return url.openConnection();
    }
    
    private InputStream getInputStream(final URLConnection con, final int sizeLimit) throws IOException {
        final InputStream inputStream = con.getInputStream();
        return (sizeLimit > 0) ? new BoundedInputStream(inputStream, this.getSizeLimit()) : inputStream;
    }
}
