/* 
 * Copyright 2015 by AVM GmbH <info@avm.de>
 *
 * This software contains free software; you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License ("License") as 
 * published by the Free Software Foundation  (version 3 of the License). 
 * This software is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the copy of the 
 * License you received along with this software for more details.
 */

package de.avm.android.tr064.net;

import java.util.ArrayList;

import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.params.AuthPolicy;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.impl.client.DefaultHttpClient;

import de.avm.android.tr064.Tr064Log;

/*
 * SSL HTTP client factory
 * - TLS
 * - optional HTTP digest or basic authentication
 */
public class SoapSSLClientFactory
{
	private static final String TAG = "SoapSSLClientFactory";

	private static final ArrayList<String> AUTH_POLYCIES;
	
	static
	{
		AUTH_POLYCIES = new ArrayList<String>(2);
		AUTH_POLYCIES.add(AuthPolicy.DIGEST);
		AUTH_POLYCIES.add(AuthPolicy.BASIC);
	}
	
	/**
	 * Create HTTP client with SSL, digest and basic authentication
	 * @param httpsPort SSL port
	 * @param username auth username
	 * @param password auth password
	 * @param pinningStore
	 * 		provides pinning config
	 * @return HTTPS client
	 */
	public static DefaultHttpClient getClientWithDigestAuth(int httpsPort,
			String username, String password, final IFingerprintPinningStore pinningStore)
	{
		return getClientWithDigestAuth(httpsPort, username, password,
				pinningStore, 0);
	}
	
	/**
	 * Create HTTP client with SSL, digest and basic authentication
	 * @param httpsPort SSL port
	 * @param username auth username
	 * @param password auth password
	 * @param pinningStore
	 * 		provides pinning config
	 * @param timeout timeout for HTTP(S) requests (0 for default)
	 * @return HTTPS client
	 */
	public static DefaultHttpClient getClientWithDigestAuth(int httpsPort,
			String username, String password,
			final IFingerprintPinningStore pinningStore, int timeout)
	{
		DefaultHttpClient client = getClient(httpsPort, pinningStore, timeout);
		
		// digest authentication
		client.getParams().setParameter(ClientContext.AUTH_SCHEME_PREF, AUTH_POLYCIES);
        client.getCredentialsProvider().setCredentials(
        		new AuthScope(AuthScope.ANY), 
        		new UsernamePasswordCredentials(username, password));

		return client;
	}

	/**
	 * Create HTTP client with SSL
	 * @param httpsPort SSL port
	 * @param pinningStore
	 * 		provides pinning config
	 * @param timeout timeout for HTTP(S) requests (0 for default)
	 * @return HTTPS client
	 */
	public static DefaultHttpClient getClient(int httpsPort,
			final IFingerprintPinningStore pinningStore, int timeout)
	{
		DefaultHttpClient client = DefaultHttpClientFactory.create(timeout);
		try
		{
	        client.getConnectionManager().getSchemeRegistry().register(
	        		new Scheme("https", SoapSSLSocketFactory
	        				.getInstance(pinningStore), httpsPort));
		}
		catch(Exception e)
		{
			Tr064Log.e(TAG, "Failed to register HTTPS scheme with HTTP client.", e);
		}
		return client;
	}
}
