/*
 * ====================================================================
 * 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */
package org.apache.hc.client5.testing.external;

import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeoutException;

import javax.net.ssl.SSLContext;

import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
import org.apache.hc.client5.http.auth.AuthScope;
import org.apache.hc.client5.http.auth.Credentials;
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
import org.apache.hc.client5.http.impl.sync.BasicCredentialsProvider;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.ssl.H2TlsStrategy;
import org.apache.hc.core5.http.HeaderElements;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.HttpVersion;
import org.apache.hc.core5.http2.HttpVersionPolicy;
import org.apache.hc.core5.ssl.SSLContexts;
import org.apache.hc.core5.util.TextUtils;
import org.apache.hc.core5.util.TimeValue;
import org.apache.hc.core5.util.Timeout;

public class HttpAsyncClientCompatibilityTest {

    public static void main(final String... args) throws Exception {
        final HttpAsyncClientCompatibilityTest[] tests = new HttpAsyncClientCompatibilityTest[] {
                new HttpAsyncClientCompatibilityTest(
                        HttpVersion.HTTP_1_1,
                        new HttpHost("localhost", 8080, "http"), null, null),
                new HttpAsyncClientCompatibilityTest(
                        HttpVersion.HTTP_1_1,
                        new HttpHost("test-httpd", 8080, "http"), new HttpHost("localhost", 8888), null),
                new HttpAsyncClientCompatibilityTest(
                        HttpVersion.HTTP_1_1,
                        new HttpHost("test-httpd", 8080, "http"), new HttpHost("localhost", 8889),
                        new UsernamePasswordCredentials("squid", "nopassword".toCharArray())),
                new HttpAsyncClientCompatibilityTest(
                        HttpVersion.HTTP_1_1,
                        new HttpHost("localhost", 8443, "https"), null, null),
                new HttpAsyncClientCompatibilityTest(
                        HttpVersion.HTTP_1_1,
                        new HttpHost("test-httpd", 8443, "https"), new HttpHost("localhost", 8888), null),
                new HttpAsyncClientCompatibilityTest(
                        HttpVersion.HTTP_1_1,
                        new HttpHost("test-httpd", 8443, "https"), new HttpHost("localhost", 8889),
                        new UsernamePasswordCredentials("squid", "nopassword".toCharArray())),
                new HttpAsyncClientCompatibilityTest(
                        HttpVersion.HTTP_2_0,
                        new HttpHost("localhost", 8080, "http"), null, null),
                new HttpAsyncClientCompatibilityTest(
                        HttpVersion.HTTP_2_0,
                        new HttpHost("localhost", 8443, "https"), null, null)
        };
        for (final HttpAsyncClientCompatibilityTest test: tests) {
            try {
                test.execute();
            } finally {
                test.shutdown();
            }
        }
    }

    private static final Timeout TIMEOUT = Timeout.ofSeconds(5);

    private final HttpVersion protocolVersion;
    private final HttpHost target;
    private final HttpHost proxy;
    private final BasicCredentialsProvider credentialsProvider;
    private final PoolingAsyncClientConnectionManager connManager;
    private final CloseableHttpAsyncClient client;

    HttpAsyncClientCompatibilityTest(
            final HttpVersion protocolVersion,
            final HttpHost target,
            final HttpHost proxy,
            final Credentials proxyCreds) throws Exception {
        this.protocolVersion = protocolVersion;
        this.target = target;
        this.proxy = proxy;
        this.credentialsProvider = new BasicCredentialsProvider();
        final RequestConfig requestConfig = RequestConfig.custom()
                .setProxy(proxy)
                .build();
        if (proxy != null && proxyCreds != null) {
            this.credentialsProvider.setCredentials(new AuthScope(proxy), proxyCreds);
        }
        final SSLContext sslContext = SSLContexts.custom()
                .loadTrustMaterial(getClass().getResource("/test-ca.keystore"), "nopassword".toCharArray()).build();
        this.connManager = PoolingAsyncClientConnectionManagerBuilder.create()
                .setTlsStrategy(new H2TlsStrategy(sslContext))
                .build();
        this.client = HttpAsyncClients.custom()
                .setVersionPolicy(this.protocolVersion == HttpVersion.HTTP_2 ? HttpVersionPolicy.FORCE_HTTP_2 : HttpVersionPolicy.FORCE_HTTP_1)
                .setConnectionManager(this.connManager)
                .setProxy(this.proxy)
                .setDefaultRequestConfig(requestConfig)
                .build();
    }

    void shutdown() throws Exception {
        client.close();
    }

    enum TestResult {OK, NOK};

    private void logResult(final TestResult result, final HttpRequest request, final String message) {
        final StringBuilder buf = new StringBuilder();
        buf.append(result);
        if (buf.length() == 2) {
            buf.append(" ");
        }
        buf.append(": ").append(protocolVersion).append(" ").append(target);
        if (proxy != null) {
            buf.append(" via ").append(proxy);
        }
        buf.append(": ");
        buf.append(request.getMethod()).append(" ").append(request.getRequestUri());
        if (message != null && !TextUtils.isBlank(message)) {
            buf.append(" -> ").append(message);
        }
        System.out.println(buf.toString());
    }

    void execute() throws Exception {

        client.start();
        // Initial ping
        {
            final HttpClientContext context = HttpClientContext.create();
            context.setCredentialsProvider(credentialsProvider);

            final SimpleHttpRequest options = SimpleHttpRequest.options(target, "*");
            final Future<SimpleHttpResponse> future = client.execute(options, context, null);
            try {
                final SimpleHttpResponse response = future.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
                final int code = response.getCode();
                if (code == HttpStatus.SC_OK) {
                    logResult(TestResult.OK, options, Objects.toString(response.getFirstHeader("server")));
                } else {
                    logResult(TestResult.NOK, options, "(status " + code + ")");
                }
            } catch (ExecutionException ex) {
                final Throwable cause = ex.getCause();
                logResult(TestResult.NOK, options, "(" + cause.getMessage() + ")");
            } catch (TimeoutException ex) {
                logResult(TestResult.NOK, options, "(time out)");
            }
        }
        // Basic GET requests
        {
            connManager.closeIdle(TimeValue.NEG_ONE_MILLISECONDS);
            final HttpClientContext context = HttpClientContext.create();
            context.setCredentialsProvider(credentialsProvider);

            final String[] requestUris = new String[] {"/", "/news.html", "/status.html"};
            for (String requestUri: requestUris) {
                final SimpleHttpRequest httpGet = SimpleHttpRequest.get(target, requestUri);
                final Future<SimpleHttpResponse> future = client.execute(httpGet, context, null);
                try {
                    final SimpleHttpResponse response = future.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
                    final int code = response.getCode();
                    if (code == HttpStatus.SC_OK) {
                        logResult(TestResult.OK, httpGet, "200");
                    } else {
                        logResult(TestResult.NOK, httpGet, "(status " + code + ")");
                    }
                } catch (ExecutionException ex) {
                    final Throwable cause = ex.getCause();
                    logResult(TestResult.NOK, httpGet, "(" + cause.getMessage() + ")");
                } catch (TimeoutException ex) {
                    logResult(TestResult.NOK, httpGet, "(time out)");
                }
            }
        }
        // Wrong target auth scope
        {
            connManager.closeIdle(TimeValue.NEG_ONE_MILLISECONDS);
            credentialsProvider.setCredentials(
                    new AuthScope("otherhost", AuthScope.ANY_PORT, "Restricted Files"),
                    new UsernamePasswordCredentials("testuser", "nopassword".toCharArray()));
            final HttpClientContext context = HttpClientContext.create();
            context.setCredentialsProvider(credentialsProvider);

            final SimpleHttpRequest httpGetSecret = SimpleHttpRequest.get(target, "/private/big-secret.txt");
            final Future<SimpleHttpResponse> future = client.execute(httpGetSecret, context, null);
            try {
                final SimpleHttpResponse response = future.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
                final int code = response.getCode();
                if (code == HttpStatus.SC_UNAUTHORIZED) {
                    logResult(TestResult.OK, httpGetSecret, "401 (wrong target auth scope)");
                } else {
                    logResult(TestResult.NOK, httpGetSecret, "(status " + code + ")");
                }
            } catch (ExecutionException ex) {
                final Throwable cause = ex.getCause();
                logResult(TestResult.NOK, httpGetSecret, "(" + cause.getMessage() + ")");
            } catch (TimeoutException ex) {
                logResult(TestResult.NOK, httpGetSecret, "(time out)");
            }
        }
        // Wrong target credentials
        {
            connManager.closeIdle(TimeValue.NEG_ONE_MILLISECONDS);
            credentialsProvider.setCredentials(
                    new AuthScope(target),
                    new UsernamePasswordCredentials("testuser", "wrong password".toCharArray()));
            final HttpClientContext context = HttpClientContext.create();
            context.setCredentialsProvider(credentialsProvider);

            final SimpleHttpRequest httpGetSecret = SimpleHttpRequest.get(target, "/private/big-secret.txt");
            final Future<SimpleHttpResponse> future = client.execute(httpGetSecret, context, null);
            try {
                final SimpleHttpResponse response = future.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
                final int code = response.getCode();
                if (code == HttpStatus.SC_UNAUTHORIZED) {
                    logResult(TestResult.OK, httpGetSecret, "401 (wrong target creds)");
                } else {
                    logResult(TestResult.NOK, httpGetSecret, "(status " + code + ")");
                }
            } catch (ExecutionException ex) {
                final Throwable cause = ex.getCause();
                logResult(TestResult.NOK, httpGetSecret, "(" + cause.getMessage() + ")");
            } catch (TimeoutException ex) {
                logResult(TestResult.NOK, httpGetSecret, "(time out)");
            }
        }
        // Correct target credentials
        {
            connManager.closeIdle(TimeValue.NEG_ONE_MILLISECONDS);
            credentialsProvider.setCredentials(
                    new AuthScope(target),
                    new UsernamePasswordCredentials("testuser", "nopassword".toCharArray()));
            final HttpClientContext context = HttpClientContext.create();
            context.setCredentialsProvider(credentialsProvider);

            final SimpleHttpRequest httpGetSecret = SimpleHttpRequest.get(target, "/private/big-secret.txt");
            final Future<SimpleHttpResponse> future = client.execute(httpGetSecret, context, null);
            try {
                final SimpleHttpResponse response = future.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
                final int code = response.getCode();
                if (code == HttpStatus.SC_OK) {
                    logResult(TestResult.OK, httpGetSecret, "200 (correct target creds)");
                } else {
                    logResult(TestResult.NOK, httpGetSecret, "(status " + code + ")");
                }
            } catch (ExecutionException ex) {
                final Throwable cause = ex.getCause();
                logResult(TestResult.NOK, httpGetSecret, "(" + cause.getMessage() + ")");
            } catch (TimeoutException ex) {
                logResult(TestResult.NOK, httpGetSecret, "(time out)");
            }
        }
        // Correct target credentials (no keep-alive)
        if (protocolVersion.lessEquals(HttpVersion.HTTP_1_1))
        {
            connManager.closeIdle(TimeValue.NEG_ONE_MILLISECONDS);
            credentialsProvider.setCredentials(
                    new AuthScope(target),
                    new UsernamePasswordCredentials("testuser", "nopassword".toCharArray()));
            final HttpClientContext context = HttpClientContext.create();
            context.setCredentialsProvider(credentialsProvider);

            final SimpleHttpRequest httpGetSecret = SimpleHttpRequest.get(target, "/private/big-secret.txt");
            httpGetSecret.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
            final Future<SimpleHttpResponse> future = client.execute(httpGetSecret, context, null);
            try {
                final SimpleHttpResponse response = future.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit());
                final int code = response.getCode();
                if (code == HttpStatus.SC_OK) {
                    logResult(TestResult.OK, httpGetSecret, "200 (correct target creds / no keep-alive)");
                } else {
                    logResult(TestResult.NOK, httpGetSecret, "(status " + code + ")");
                }
            } catch (ExecutionException ex) {
                final Throwable cause = ex.getCause();
                logResult(TestResult.NOK, httpGetSecret, "(" + cause.getMessage() + ")");
            } catch (TimeoutException ex) {
                logResult(TestResult.NOK, httpGetSecret, "(time out)");
            }
        }
    }

}
