/*
 * 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.commons.vfs2.provider.http5;

import java.io.File;
import java.io.IOException;
import java.net.ProxySelector;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;

import org.apache.commons.vfs2.Capability;
import org.apache.commons.vfs2.FileName;
import org.apache.commons.vfs2.FileSystem;
import org.apache.commons.vfs2.FileSystemConfigBuilder;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.FileSystemOptions;
import org.apache.commons.vfs2.UserAuthenticationData;
import org.apache.commons.vfs2.UserAuthenticator;
import org.apache.commons.vfs2.provider.AbstractOriginatingFileProvider;
import org.apache.commons.vfs2.provider.GenericFileName;
import org.apache.commons.vfs2.util.UserAuthenticatorUtils;
import org.apache.hc.client5.http.auth.AuthCache;
import org.apache.hc.client5.http.auth.AuthScope;
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.cookie.BasicCookieStore;
import org.apache.hc.client5.http.cookie.Cookie;
import org.apache.hc.client5.http.cookie.CookieStore;
import org.apache.hc.client5.http.impl.auth.BasicAuthCache;
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
import org.apache.hc.client5.http.impl.auth.BasicScheme;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.impl.routing.DefaultProxyRoutePlanner;
import org.apache.hc.client5.http.impl.routing.SystemDefaultRoutePlanner;
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.routing.HttpRoutePlanner;
import org.apache.hc.client5.http.ssl.DefaultHostnameVerifier;
import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder;
import org.apache.hc.client5.http.ssl.TrustAllStrategy;
import org.apache.hc.core5.http.ConnectionReuseStrategy;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
import org.apache.hc.core5.http.io.SocketConfig;
import org.apache.hc.core5.http.message.BasicHeader;
import org.apache.hc.core5.http.ssl.TLS;
import org.apache.hc.core5.ssl.SSLContextBuilder;
import org.apache.hc.core5.util.Timeout;

/**
 * {@code FileProvider} implementation using HttpComponents HttpClient v5 library.
 *
 * @since 2.5.0
 */
public class Http5FileProvider extends AbstractOriginatingFileProvider {

    /** Authenticator information. */
    static final UserAuthenticationData.Type[] AUTHENTICATOR_TYPES =
            new UserAuthenticationData.Type[] {
                    UserAuthenticationData.USERNAME,
                    UserAuthenticationData.PASSWORD
                    };

    /** FileProvider capabilities */
    static final Collection<Capability> CAPABILITIES =
            Collections.unmodifiableCollection(
                    Arrays.asList(
                            Capability.GET_TYPE,
                            Capability.READ_CONTENT,
                            Capability.URI,
                            Capability.GET_LAST_MODIFIED,
                            Capability.ATTRIBUTES,
                            Capability.RANDOM_ACCESS_READ,
                            Capability.DIRECTORY_READ_CONTENT
                            )
                    );

    /**
     * Constructs a new provider.
     */
    public Http5FileProvider() {
        setFileNameParser(Http5FileNameParser.getInstance());
    }

    private HttpClientConnectionManager createConnectionManager(final Http5FileSystemConfigBuilder builder,
            final FileSystemOptions fileSystemOptions) throws FileSystemException {

        final SocketConfig socketConfig =
                SocketConfig
                .custom()
                .setSoTimeout(Timeout.ofMilliseconds(builder.getSoTimeoutDuration(fileSystemOptions).toMillis()))
                .build();

        final String[] tlsVersions = builder.getTlsVersions(fileSystemOptions).split("\\s*,\\s*");

        final TLS[] tlsArray = Arrays.stream(tlsVersions).map(TLS::valueOf).toArray(TLS[]::new);

        final SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder.create()
                .setSslContext(createSSLContext(builder, fileSystemOptions))
                .setHostnameVerifier(createHostnameVerifier(builder, fileSystemOptions))
                .setTlsVersions(tlsArray)
                .build();

        return PoolingHttpClientConnectionManagerBuilder.create()
                .setSSLSocketFactory(sslSocketFactory)
                .setMaxConnTotal(builder.getMaxTotalConnections(fileSystemOptions))
                .setMaxConnPerRoute(builder.getMaxConnectionsPerHost(fileSystemOptions))
                .setDefaultSocketConfig(socketConfig)
                .build();
    }

    private CookieStore createDefaultCookieStore(final Http5FileSystemConfigBuilder builder,
            final FileSystemOptions fileSystemOptions) {
        final CookieStore cookieStore = new BasicCookieStore();
        final Cookie[] cookies = builder.getCookies(fileSystemOptions);

        if (cookies != null) {
            Arrays.stream(cookies).forEach(cookieStore::addCookie);
        }

        return cookieStore;
    }

    private RequestConfig createDefaultRequestConfig(final Http5FileSystemConfigBuilder builder,
            final FileSystemOptions fileSystemOptions) {
        return RequestConfig.custom()
                .setConnectTimeout(Timeout.ofMilliseconds(builder.getSoTimeoutDuration(fileSystemOptions).toMillis()))
                .build();
    }

    private HostnameVerifier createHostnameVerifier(final Http5FileSystemConfigBuilder builder,
            final FileSystemOptions fileSystemOptions) throws FileSystemException {
        if (!builder.isHostnameVerificationEnabled(fileSystemOptions)) {
            return NoopHostnameVerifier.INSTANCE;
        }

        return new DefaultHostnameVerifier();
    }

    /**
     * Create an {@link HttpClient} object for an http4 file system.
     *
     * @param builder Configuration options builder for http4 provider
     * @param rootName The root path
     * @param fileSystemOptions The file system options
     * @return an {@link HttpClient} object
     * @throws FileSystemException if an error occurs.
     */
    protected HttpClient createHttpClient(final Http5FileSystemConfigBuilder builder, final GenericFileName rootName,
            final FileSystemOptions fileSystemOptions) throws FileSystemException {
        return createHttpClientBuilder(builder, rootName, fileSystemOptions).build();
    }

    /**
     * Create an {@link HttpClientBuilder} object. Invoked by {@link #createHttpClient(Http5FileSystemConfigBuilder, GenericFileName, FileSystemOptions)}.
     *
     * @param builder Configuration options builder for HTTP4 provider
     * @param rootName The root path
     * @param fileSystemOptions The FileSystem options
     * @return an {@link HttpClientBuilder} object
     * @throws FileSystemException if an error occurs
     */
    protected HttpClientBuilder createHttpClientBuilder(final Http5FileSystemConfigBuilder builder, final GenericFileName rootName,
            final FileSystemOptions fileSystemOptions) throws FileSystemException {
        final List<Header> defaultHeaders = new ArrayList<>();
        defaultHeaders.add(new BasicHeader(HttpHeaders.USER_AGENT, builder.getUserAgent(fileSystemOptions)));

        final ConnectionReuseStrategy connectionReuseStrategy = builder.isKeepAlive(fileSystemOptions)
                ? DefaultConnectionReuseStrategy.INSTANCE
                : (request, response, context) -> false;

        final HttpClientBuilder httpClientBuilder =
                HttpClients.custom()
                .setRoutePlanner(createHttpRoutePlanner(builder, fileSystemOptions))
                .setConnectionManager(createConnectionManager(builder, fileSystemOptions))
                .setConnectionReuseStrategy(connectionReuseStrategy)
                .setDefaultRequestConfig(createDefaultRequestConfig(builder, fileSystemOptions))
                .setDefaultHeaders(defaultHeaders)
                .setDefaultCookieStore(createDefaultCookieStore(builder, fileSystemOptions));

        if (!builder.getFollowRedirect(fileSystemOptions)) {
            httpClientBuilder.disableRedirectHandling();
        }

        return httpClientBuilder;
    }

    /**
     * Create an {@link HttpClientContext} object for an http4 file system.
     *
     * @param builder Configuration options builder for http4 provider
     * @param rootName The root path
     * @param fileSystemOptions The FileSystem options
     * @param authData The {@code UserAuthentiationData} object
     * @return an {@link HttpClientContext} object
     * @throws FileSystemException if an error occurs
     */
    protected HttpClientContext createHttpClientContext(final Http5FileSystemConfigBuilder builder,
            final GenericFileName rootName, final FileSystemOptions fileSystemOptions,
            final UserAuthenticationData authData) throws FileSystemException {

        final HttpClientContext clientContext = HttpClientContext.create();
        final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
        clientContext.setCredentialsProvider(credsProvider);

        final String username = UserAuthenticatorUtils.toString(UserAuthenticatorUtils.getData(authData,
                UserAuthenticationData.USERNAME, UserAuthenticatorUtils.toChar(rootName.getUserName())));
        final char[] password = UserAuthenticatorUtils.getData(authData,
                UserAuthenticationData.PASSWORD, UserAuthenticatorUtils.toChar(rootName.getPassword()));

        if (username != null && !username.isEmpty()) {
            // set root port
            credsProvider.setCredentials(new AuthScope(rootName.getHostName(), rootName.getPort()),
                    new UsernamePasswordCredentials(username, password));
        }

        final HttpHost proxyHost = getProxyHttpHost(builder, fileSystemOptions);

        if (proxyHost != null) {
            final UserAuthenticator proxyAuth = builder.getProxyAuthenticator(fileSystemOptions);

            if (proxyAuth != null) {
                final UserAuthenticationData proxyAuthData = UserAuthenticatorUtils.authenticate(proxyAuth,
                        new UserAuthenticationData.Type[] { UserAuthenticationData.USERNAME,
                                UserAuthenticationData.PASSWORD });

                if (proxyAuthData != null) {
                    final UsernamePasswordCredentials proxyCreds = new UsernamePasswordCredentials(
                            UserAuthenticatorUtils.toString(
                                    UserAuthenticatorUtils.getData(authData, UserAuthenticationData.USERNAME, null)),
                            UserAuthenticatorUtils.getData(authData, UserAuthenticationData.PASSWORD, null));

                    // set proxy host port
                    credsProvider.setCredentials(new AuthScope(proxyHost.getHostName(), proxyHost.getPort()),
                            proxyCreds);
                }

                if (builder.isPreemptiveAuth(fileSystemOptions)) {
                    final AuthCache authCache = new BasicAuthCache();
                    final BasicScheme basicAuth = new BasicScheme();
                    authCache.put(proxyHost, basicAuth);
                    clientContext.setAuthCache(authCache);
                }
            }
        }

        return clientContext;
    }

    private HttpRoutePlanner createHttpRoutePlanner(final Http5FileSystemConfigBuilder builder,
            final FileSystemOptions fileSystemOptions) {
        final HttpHost proxyHost = getProxyHttpHost(builder, fileSystemOptions);

        if (proxyHost != null) {
            return new DefaultProxyRoutePlanner(proxyHost);
        }

        return new SystemDefaultRoutePlanner(ProxySelector.getDefault());
    }

    /**
     * Create {@link SSLContext} for HttpClient. Invoked by {@link #createHttpClientBuilder(Http5FileSystemConfigBuilder, GenericFileName, FileSystemOptions)}.
     *
     * @param builder Configuration options builder for HTTP4 provider
     * @param fileSystemOptions The FileSystem options
     * @return a {@link SSLContext} for HttpClient
     * @throws FileSystemException if an error occurs
     */
    protected SSLContext createSSLContext(final Http5FileSystemConfigBuilder builder,
            final FileSystemOptions fileSystemOptions) throws FileSystemException {
        try {
            final SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
            sslContextBuilder.setKeyStoreType(builder.getKeyStoreType(fileSystemOptions));

            File keystoreFileObject = null;
            final String keystoreFile = builder.getKeyStoreFile(fileSystemOptions);

            if (keystoreFile != null && !keystoreFile.isEmpty()) {
                keystoreFileObject = new File(keystoreFile);
            }

            if (keystoreFileObject != null && keystoreFileObject.exists()) {
                final String keystorePass = builder.getKeyStorePass(fileSystemOptions);
                final char[] keystorePassChars = (keystorePass != null) ? keystorePass.toCharArray() : null;
                sslContextBuilder.loadTrustMaterial(keystoreFileObject, keystorePassChars, TrustAllStrategy.INSTANCE);
            } else {
                sslContextBuilder.loadTrustMaterial(TrustAllStrategy.INSTANCE);
            }

            return sslContextBuilder.build();
        } catch (final KeyStoreException e) {
            throw new FileSystemException("Keystore error. " + e.getMessage(), e);
        } catch (final KeyManagementException e) {
            throw new FileSystemException("Cannot retrieve keys. " + e.getMessage(), e);
        } catch (final NoSuchAlgorithmException e) {
            throw new FileSystemException("Algorithm error. " + e.getMessage(), e);
        } catch (final CertificateException e) {
            throw new FileSystemException("Certificate error. " + e.getMessage(), e);
        } catch (final IOException e) {
            throw new FileSystemException("Cannot open key file. " + e.getMessage(), e);
        }
    }

    @Override
    protected FileSystem doCreateFileSystem(final FileName name, final FileSystemOptions fileSystemOptions)
            throws FileSystemException {
        final GenericFileName rootName = (GenericFileName) name;

        UserAuthenticationData authData = null;
        HttpClient httpClient;
        HttpClientContext httpClientContext;

        try {
            final Http5FileSystemConfigBuilder builder = Http5FileSystemConfigBuilder.getInstance();
            authData = UserAuthenticatorUtils.authenticate(fileSystemOptions, AUTHENTICATOR_TYPES);
            httpClientContext = createHttpClientContext(builder, rootName, fileSystemOptions, authData);
            httpClient = createHttpClient(builder, rootName, fileSystemOptions);
        } finally {
            UserAuthenticatorUtils.cleanup(authData);
        }

        return new Http5FileSystem(rootName, fileSystemOptions, httpClient, httpClientContext);
    }

    @Override
    public Collection<Capability> getCapabilities() {
        return CAPABILITIES;
    }

    @Override
    public FileSystemConfigBuilder getConfigBuilder() {
        return Http5FileSystemConfigBuilder.getInstance();
    }

    private HttpHost getProxyHttpHost(final Http5FileSystemConfigBuilder builder,
            final FileSystemOptions fileSystemOptions) {
        final String proxyScheme = builder.getProxyScheme(fileSystemOptions);
        final String proxyHost = builder.getProxyHost(fileSystemOptions);
        final int proxyPort = builder.getProxyPort(fileSystemOptions);

        if (proxyHost != null && !proxyHost.isEmpty() && proxyPort > 0) {
            return new HttpHost(proxyScheme, proxyHost, proxyPort);
        }

        return null;
    }

}
