/*******************************************************************************
 * Copyright (c) 2011, 2014 Tasktop Technologies and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Tasktop Technologies - initial API and implementation
 *******************************************************************************/

package org.eclipse.mylyn.commons.repositories.http.core;

import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URI;
import java.net.UnknownHostException;
import java.util.Locale;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.NTCredentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.params.AuthPolicy;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.scheme.SchemeSocketFactory;
import org.apache.http.impl.EnglishReasonPhraseCatalog;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.eclipse.core.net.proxy.IProxyData;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.mylyn.commons.core.CoreUtil;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.commons.core.net.AuthenticatedProxy;
import org.eclipse.mylyn.commons.core.net.NetUtil;
import org.eclipse.mylyn.commons.core.operations.CancellableOperationMonitorThread;
import org.eclipse.mylyn.commons.core.operations.ICancellableOperation;
import org.eclipse.mylyn.commons.core.operations.IOperationMonitor;
import org.eclipse.mylyn.commons.core.operations.OperationUtil;
import org.eclipse.mylyn.commons.repositories.core.RepositoryLocation;
import org.eclipse.mylyn.commons.repositories.core.auth.AuthenticationType;
import org.eclipse.mylyn.commons.repositories.core.auth.UserCredentials;
import org.eclipse.mylyn.internal.commons.repositories.http.core.IdleConnectionMonitorThread;
import org.eclipse.mylyn.internal.commons.repositories.http.core.PollingProtocolSocketFactory;
import org.eclipse.mylyn.internal.commons.repositories.http.core.PollingSslProtocolSocketFactory;

/**
 * @author Steffen Pingel
 * @author Shawn Minto
 * @author Christian Janz
 * @noinstantiate This class is not intended to be instantiated by clients.
 */
public class HttpUtil {

	static {
		CoreUtil.initializeLoggingSettings();
	}

	@SuppressWarnings("unused")
	private static final int BUFFER_SIZE = 4096;

	@SuppressWarnings("unused")
	private static final long CLOSE_TIMEOUT = -1;

	/**
	 * @see IdleConnectionMonitorThread
	 */
	private static final int CONNECTION_TIMEOUT_INTERVAL = 1 * 30 * 1000;

	private static final int CONNNECT_TIMEOUT = 60 * 1000;

	private static final int HTTP_PORT = 80;

	private static final int HTTPS_PORT = 443;

	private static final int POLL_INTERVAL = 500;

	private static final int SOCKET_TIMEOUT = 3 * 60 * 1000;

	@SuppressWarnings("unused")
	private static final int POLL_ATTEMPTS = SOCKET_TIMEOUT / POLL_INTERVAL;

	private static SchemeSocketFactory socketFactory = new PollingProtocolSocketFactory();

	private static SchemeSocketFactory sslSocketFactory = new PollingSslProtocolSocketFactory();

	static final String ID_PLUGIN = "org.eclipse.mylyn.commons.repositories.http"; //$NON-NLS-1$

	private static ThreadSafeClientConnManager connectionManager;

	static final String CONTEXT_KEY_MONITOR_THREAD = CancellableOperationMonitorThread.class.getName();

	public static void configureClient(AbstractHttpClient client, String userAgent) {
		HttpClientParams.setCookiePolicy(client.getParams(), CookiePolicy.BEST_MATCH);

		if (userAgent != null) {
			HttpProtocolParams.setUserAgent(client.getParams(), userAgent);
		}
		HttpProtocolParams.setUseExpectContinue(client.getParams(), true);
		client.getParams().setBooleanParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true);

		HttpConnectionParams.setConnectionTimeout(client.getParams(), CONNNECT_TIMEOUT);
		HttpConnectionParams.setSoTimeout(client.getParams(), SOCKET_TIMEOUT);

		//AuthParams.setCredentialCharset(client.getParams(), "UTF-8");
	}

	public static void configureAuthentication(AbstractHttpClient client, RepositoryLocation location) {
		UserCredentials credentials = location.getCredentials(AuthenticationType.HTTP);
		if (credentials != null) {
			configureAuthentication(client, location, credentials);
		}
	}

	public static void configureAuthentication(AbstractHttpClient client, RepositoryLocation location,
			UserCredentials credentials) {
		Assert.isNotNull(client);
		Assert.isNotNull(location);
		Assert.isNotNull(credentials);
		String url = location.getUrl();
		Assert.isNotNull(url, "The location url must not be null"); //$NON-NLS-1$

		String host = NetUtil.getHost(url);
		int port = NetUtil.getPort(url);

		NTCredentials ntlmCredentials = getNtCredentials(credentials, ""); //$NON-NLS-1$
		if (ntlmCredentials != null) {
			AuthScope authScopeNtlm = new AuthScope(host, port, AuthScope.ANY_REALM, AuthPolicy.NTLM);
			client.getCredentialsProvider().setCredentials(authScopeNtlm, ntlmCredentials);
		}

		UsernamePasswordCredentials usernamePasswordCredentials = getUserNamePasswordCredentials(credentials);
		AuthScope authScopeAny = new AuthScope(host, port, AuthScope.ANY_REALM);
		client.getCredentialsProvider().setCredentials(authScopeAny, usernamePasswordCredentials);
	}

	public static HttpHost createHost(HttpRequestBase method) {
		URI uri = method.getURI();
		return new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());
	}

	public static HttpResponse execute(final AbstractHttpClient client, final HttpContext context,
			final HttpRequestBase method, IProgressMonitor monitor) throws IOException {
		return execute(client, createHost(method), context, method, monitor);
	}

	public static HttpResponse execute(final AbstractHttpClient client, final HttpHost host, final HttpContext context,
			final HttpRequestBase method, final IProgressMonitor progress) throws IOException {
		Assert.isNotNull(client);
		Assert.isNotNull(method);

		final IOperationMonitor monitor = OperationUtil.convert(progress);
		ICancellableOperation operation = new ICancellableOperation() {
			@Override
			public void abort() {
				method.abort();
			}

			@Override
			public boolean isCanceled() {
				return monitor.isCanceled();
			}
		};

		CancellableOperationMonitorThread thread = null;
		if (context != null) {
			thread = (CancellableOperationMonitorThread) context.getAttribute(CONTEXT_KEY_MONITOR_THREAD);
		}
		if (thread != null) {
			thread.addOperation(operation);
		}
		try {
			return client.execute(host, method, context);
		} catch (InterruptedIOException e) {
			if (monitor.isCanceled()) {
				throw new OperationCanceledException();
			}
			throw e;
		} finally {
			if (thread != null) {
				thread.removeOperation(operation);
			}
		}
	}

	public static NTCredentials getNtCredentials(UserCredentials credentials, String workstation) {
		String username = credentials.getUserName();
		int i = username.indexOf("\\"); //$NON-NLS-1$
		if (i > 0 && i < username.length() - 1) {
//			try {
//				InetAddress localHost = InetAddress.getLocalHost();
//				if (localHost != null) {
//					hostName = localHost.getHostName();
//				}
//			} catch (UnknownHostException e) {
//				StatusHandler.log(new Status(IStatus.ERROR, ID_PLUGIN,
//						"Unable to get hostname.  Defaulting to servers host.", e));
//			}
			return new NTCredentials(username.substring(i + 1), credentials.getPassword(), workstation,
					username.substring(0, i));
		}
		return null;
	}

	public static UsernamePasswordCredentials getUserNamePasswordCredentials(UserCredentials credentials) {
		return new UsernamePasswordCredentials(credentials.getUserName(), credentials.getPassword());
	}

	public static InputStream getResponseBodyAsStream(HttpEntity entity, IProgressMonitor monitor) throws IOException {
		monitor = OperationUtil.convert(monitor);
		return entity.getContent();
//		return new PollingInputStream(new TimeoutInputStream(entity.getContent(), BUFFER_SIZE, POLL_INTERVAL,
//				CLOSE_TIMEOUT), POLL_ATTEMPTS, monitor);
	}

	public static SchemeRegistry getSchemeRegistry() {
		SchemeRegistry schemeRegistry = new SchemeRegistry();
		schemeRegistry.register(new Scheme("http", HTTP_PORT, socketFactory)); //$NON-NLS-1$
		schemeRegistry.register(new Scheme("https", HTTPS_PORT, sslSocketFactory)); //$NON-NLS-1$
		return schemeRegistry;
	}

	public static void configureProxy(AbstractHttpClient client, RepositoryLocation location) {
		Assert.isNotNull(client);
		Assert.isNotNull(location);
		String url = location.getUrl();
		Assert.isNotNull(url, "The location url must not be null"); //$NON-NLS-1$

		String host = NetUtil.getHost(url);
		Proxy proxy;
		if (NetUtil.isUrlHttps(url)) {
			proxy = location.getProxyForHost(host, IProxyData.HTTPS_PROXY_TYPE);
		} else {
			proxy = location.getProxyForHost(host, IProxyData.HTTP_PROXY_TYPE);
		}

		if (proxy != null && !Proxy.NO_PROXY.equals(proxy)) {
			InetSocketAddress address = (InetSocketAddress) proxy.address();

			client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,
					new HttpHost(address.getHostName(), address.getPort()));

			if (proxy instanceof AuthenticatedProxy) {
				AuthenticatedProxy authProxy = (AuthenticatedProxy) proxy;
				Credentials credentials = getCredentials(authProxy.getUserName(), authProxy.getPassword(),
						address.getAddress(), false);
				if (credentials instanceof NTCredentials) {
					AuthScope proxyAuthScopeNTLM = new AuthScope(address.getHostName(), address.getPort(),
							AuthScope.ANY_REALM, AuthPolicy.NTLM);
					client.getCredentialsProvider().setCredentials(proxyAuthScopeNTLM, credentials);

					AuthScope proxyAuthScopeAny = new AuthScope(address.getHostName(), address.getPort(),
							AuthScope.ANY_REALM);
					Credentials usernamePasswordCredentials = getCredentials(authProxy.getUserName(),
							authProxy.getPassword(), address.getAddress(), true);
					client.getCredentialsProvider().setCredentials(proxyAuthScopeAny, usernamePasswordCredentials);

				} else {
					AuthScope proxyAuthScope = new AuthScope(address.getHostName(), address.getPort(),
							AuthScope.ANY_REALM);
					client.getCredentialsProvider().setCredentials(proxyAuthScope, credentials);
				}
			}
		} else {
			client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, null);
		}
	}

	static Credentials getCredentials(final String username, final String password, final InetAddress address,
			boolean forceUserNamePassword) {
		int i = username.indexOf("\\"); //$NON-NLS-1$
		if (i > 0 && i < username.length() - 1 && address != null && !forceUserNamePassword) {
			String hostName = address.getHostName();
			try {
				InetAddress localHost = InetAddress.getLocalHost();
				if (localHost != null) {
					hostName = localHost.getHostName();
				}
			} catch (UnknownHostException e) {
				StatusHandler.log(new Status(IStatus.ERROR, ID_PLUGIN,
						"Unable to get hostname.  Defaulting to servers host.", e)); //$NON-NLS-1$
			}
			if (hostName == null) {
				hostName = address.getHostName();
			}
			return new NTCredentials(username.substring(i + 1), password, hostName, username.substring(0, i));
		} else {
			return new UsernamePasswordCredentials(username, password);
		}
	}

	public static synchronized ThreadSafeClientConnManager getConnectionManager() {
		if (connectionManager == null) {
			connectionManager = new ThreadSafeClientConnManager(HttpUtil.getSchemeRegistry());
			if (CoreUtil.TEST_MODE) {
				connectionManager.setDefaultMaxPerRoute(2);
			} else {
				connectionManager.setDefaultMaxPerRoute(NetUtil.getMaxHttpConnectionsPerHost());
				connectionManager.setMaxTotal(NetUtil.getMaxHttpConnections());
			}

			IdleConnectionMonitorThread thread = new IdleConnectionMonitorThread(CONNECTION_TIMEOUT_INTERVAL);
			thread.setTimeout(CONNNECT_TIMEOUT);
			thread.addConnectionManager(connectionManager);
			thread.start();
		}
		return connectionManager;
	}

	public static String getStatusText(int statusCode) {
		return EnglishReasonPhraseCatalog.INSTANCE.getReason(statusCode, Locale.getDefault());
	}

	public static void release(HttpRequest request, HttpResponse response, IProgressMonitor monitor) {
		Assert.isNotNull(request);
		Assert.isNotNull(response);
		if (monitor != null && monitor.isCanceled() && request instanceof HttpUriRequest) {
			// force a connection close on cancel to avoid blocking to do reading the remainder of the response
			try {
				((HttpUriRequest) request).abort();
			} catch (UnsupportedOperationException e) {
				// fall back to standard close
				consume(request, response);
			}
		} else {
			consume(request, response);
		}
	}

	private static void consume(HttpRequest request, HttpResponse response) {
		try {
			EntityUtils.consume(response.getEntity());
		} catch (IOException e) {
			// if construction of the stream fails the connection has to be aborted to be released
			try {
				((HttpUriRequest) request).abort();
			} catch (UnsupportedOperationException e2) {
			}
		} catch (NullPointerException e2) {
			// XXX work-around for bug 368830
		}
	}

}
