/*
 * ====================================================================
 * 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.sync;

import java.io.IOException;
import java.security.Principal;

import org.apache.hc.client5.http.auth.AuthScheme;
import org.apache.hc.client5.http.auth.AuthSchemeProvider;
import org.apache.hc.client5.http.auth.AuthScope;
import org.apache.hc.client5.http.auth.Credentials;
import org.apache.hc.client5.http.config.AuthSchemes;
import org.apache.hc.client5.http.impl.auth.SPNegoScheme;
import org.apache.hc.client5.http.impl.sync.BasicCredentialsProvider;
import org.apache.hc.client5.http.impl.sync.HttpClients;
import org.apache.hc.client5.http.sync.methods.HttpGet;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.HttpException;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.config.Registry;
import org.apache.hc.core5.http.config.RegistryBuilder;
import org.apache.hc.core5.http.io.HttpRequestHandler;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.message.BasicHeader;
import org.apache.hc.core5.http.protocol.HttpContext;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSCredential;
import org.ietf.jgss.GSSManager;
import org.ietf.jgss.GSSName;
import org.ietf.jgss.Oid;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.ArgumentMatchers;
import org.mockito.Mockito;

/**
 * Tests for {@link SPNegoScheme}.
 */
public class TestSPNegoScheme extends LocalServerTestBase {

    /**
     * This service will continue to ask for authentication.
     */
    private static class PleaseNegotiateService implements HttpRequestHandler {

        @Override
        public void handle(
                final ClassicHttpRequest request,
                final ClassicHttpResponse response,
                final HttpContext context) throws HttpException, IOException {
            response.setCode(HttpStatus.SC_UNAUTHORIZED);
            response.addHeader(new BasicHeader("WWW-Authenticate", "Negotiate blablabla"));
            response.addHeader(new BasicHeader("Connection", "Keep-Alive"));
            response.setEntity(new StringEntity("auth required "));
        }
    }

    /**
     * NegotatieScheme with a custom GSSManager that does not require any Jaas or
     * Kerberos configuration.
     *
     */
    private static class NegotiateSchemeWithMockGssManager extends SPNegoScheme {

        GSSManager manager = Mockito.mock(GSSManager.class);
        GSSName name = Mockito.mock(GSSName.class);
        GSSContext context = Mockito.mock(GSSContext.class);

        NegotiateSchemeWithMockGssManager() throws Exception {
            super(true);
            Mockito.when(context.initSecContext(
                    ArgumentMatchers.<byte[]>any(), ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt()))
                    .thenReturn("12345678".getBytes());
            Mockito.when(manager.createName(
                    ArgumentMatchers.anyString(), ArgumentMatchers.<Oid>any()))
                    .thenReturn(name);
            Mockito.when(manager.createContext(
                    ArgumentMatchers.<GSSName>any(), ArgumentMatchers.<Oid>any(),
                    ArgumentMatchers.<GSSCredential>any(), ArgumentMatchers.anyInt()))
                    .thenReturn(context);
        }

        @Override
        protected GSSManager getManager() {
            return manager;
        }

    }

    private static class UseJaasCredentials implements Credentials {

        @Override
        public char[] getPassword() {
            return null;
        }

        @Override
        public Principal getUserPrincipal() {
            return null;
        }

    }

    private static class NegotiateSchemeProviderWithMockGssManager implements AuthSchemeProvider {

        NegotiateSchemeWithMockGssManager scheme;

        NegotiateSchemeProviderWithMockGssManager() throws Exception {
            scheme = new NegotiateSchemeWithMockGssManager();
        }

        @Override
        public AuthScheme create(final HttpContext context) {
            return scheme;
        }

    }

    /**
     * Tests that the client will stop connecting to the server if
     * the server still keep asking for a valid ticket.
     */
    @Test
    public void testDontTryToAuthenticateEndlessly() throws Exception {
        this.serverBootstrap.registerHandler("*", new PleaseNegotiateService());
        final HttpHost target = start();

        final AuthSchemeProvider nsf = new NegotiateSchemeProviderWithMockGssManager();
        final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        final Credentials use_jaas_creds = new UseJaasCredentials();
        credentialsProvider.setCredentials(new AuthScope(null, -1, null), use_jaas_creds);

        final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
            .register(AuthSchemes.SPNEGO, nsf)
            .build();
        this.httpclient = HttpClients.custom()
            .setDefaultAuthSchemeRegistry(authSchemeRegistry)
            .setDefaultCredentialsProvider(credentialsProvider)
            .build();

        final String s = "/path";
        final HttpGet httpget = new HttpGet(s);
        final ClassicHttpResponse response = this.httpclient.execute(target, httpget);
        EntityUtils.consume(response.getEntity());

        Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
    }

    /**
     * Javadoc specifies that {@link GSSContext#initSecContext(byte[], int, int)} can return null
     * if no token is generated. Client should be able to deal with this response.
     */
    @Test
    public void testNoTokenGeneratedError() throws Exception {
        this.serverBootstrap.registerHandler("*", new PleaseNegotiateService());
        final HttpHost target = start();

        final AuthSchemeProvider nsf = new NegotiateSchemeProviderWithMockGssManager();

        final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        final Credentials use_jaas_creds = new UseJaasCredentials();
        credentialsProvider.setCredentials(new AuthScope(null, -1, null), use_jaas_creds);

        final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
            .register(AuthSchemes.SPNEGO, nsf)
            .build();
        this.httpclient = HttpClients.custom()
            .setDefaultAuthSchemeRegistry(authSchemeRegistry)
            .setDefaultCredentialsProvider(credentialsProvider)
            .build();

        final String s = "/path";
        final HttpGet httpget = new HttpGet(s);
        final ClassicHttpResponse response = this.httpclient.execute(target, httpget);
        EntityUtils.consume(response.getEntity());

        Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
    }

}
