package net.sf.taverna.t2.activities.rest;

import java.net.URI;
import java.net.URLEncoder;
import java.security.Principal;

import javax.management.remote.JMXPrincipal;

import net.sf.taverna.t2.security.credentialmanager.CredentialManager;
import net.sf.taverna.t2.security.credentialmanager.UsernamePassword;

import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
//import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.log4j.Logger;

/**
 * This CredentialsProvider acts as a mediator between the Apache HttpClient and
 * Taverna's CredentialManager that stores all user's credentials.
 *
 * The only role of it is to retrieve stored details from CredentialManager when
 * they are required for HTTP authentication.
 *
 * @author Sergejs Aleksejevs
 * @author Alex Nenadic
 */
public class RESTActivityCredentialsProvider extends BasicCredentialsProvider {
	private static Logger logger = Logger.getLogger(RESTActivityCredentialsProvider.class);
	
	private static final int DEFAULT_HTTP_PORT = 80;
	private static final int DEFAULT_HTTPS_PORT = 443;
	
	private static final String HTTP_PROTOCOL = "http";
	private static final String HTTPS_PROTOCOL = "https";
	
	private CredentialManager credentialManager;
	
	public RESTActivityCredentialsProvider(CredentialManager credentialManager) {
		this.credentialManager = credentialManager;
	}
	
	@Override
	public Credentials getCredentials(AuthScope authscope) {
		logger.info("Looking for credentials for: Host - " + authscope.getHost() + ";" + "Port - "
				+ authscope.getPort() + ";" + "Realm - " + authscope.getRealm() + ";"
				+ "Authentication scheme - " + authscope.getScheme());
		
		// Ask the superclass first
		Credentials creds = super.getCredentials(authscope);
		if (creds != null) {
			/*
			 * We have used setCredentials() on this class (for proxy host,
			 * port, username,password) just before we invoked the http request,
			 * which will then pick the proxy credentials up from here.
			 */
			return creds;
		}
		
		// Otherwise, ask Credential Manager if is can provide the credential
		String AUTHENTICATION_REQUEST_MSG = "This REST service requires authentication in "
				+ authscope.getRealm();

		try {
			UsernamePassword credentials = null;

			/*
			 * if port is 80 - use HTTP, don't append port if port is 443 - use
			 * HTTPS, don't append port any other port - append port + do 2
			 * tests:
			 * 
			 * --- test HTTPS first has...()
			 * --- if not there, do get...() for HTTP (which will save the thing)
			 *
			 * (save both these entries for HTTP + HTTPS if not there)
			 */

			// build the service URI back to front
			StringBuilder serviceURI = new StringBuilder();
			serviceURI.insert(0, "/#" + URLEncoder.encode(authscope.getRealm(), "UTF-16"));
			if (authscope.getPort() != DEFAULT_HTTP_PORT
					&& authscope.getPort() != DEFAULT_HTTPS_PORT) {
				// non-default port - add port name to the URI
				serviceURI.insert(0, ":" + authscope.getPort());
			}
			serviceURI.insert(0, authscope.getHost());
			serviceURI.insert(0, "://");

			// now the URI is complete, apart from the protocol name
			if (authscope.getPort() == DEFAULT_HTTP_PORT
					|| authscope.getPort() == DEFAULT_HTTPS_PORT) {
				// definitely HTTP or HTTPS
				serviceURI.insert(0, (authscope.getPort() == DEFAULT_HTTP_PORT ? HTTP_PROTOCOL
						: HTTPS_PROTOCOL));

				// request credentials from CrendentialManager
				credentials = credentialManager.getUsernameAndPasswordForService(
						URI.create(serviceURI.toString()), true, AUTHENTICATION_REQUEST_MSG);
			} else {
				/*
				 * non-default port - will need to try both HTTP and HTTPS; just
				 * check (no pop-up will be shown) if credentials are there -
				 * one protocol that matched will be used; if
				 */
				if (credentialManager.hasUsernamePasswordForService(URI.create(HTTPS_PROTOCOL
						+ serviceURI.toString()))) {
					credentials = credentialManager.getUsernameAndPasswordForService(
							URI.create(HTTPS_PROTOCOL + serviceURI.toString()), true,
							AUTHENTICATION_REQUEST_MSG);
				} else if (credentialManager.hasUsernamePasswordForService(URI.create(HTTP_PROTOCOL
						+ serviceURI.toString()))) {
					credentials = credentialManager.getUsernameAndPasswordForService(
							URI.create(HTTP_PROTOCOL + serviceURI.toString()), true,
							AUTHENTICATION_REQUEST_MSG);
				} else {
					/*
					 * Neither of the two options succeeded, request details with a
					 * popup for HTTP...
					 */
					credentials = credentialManager.getUsernameAndPasswordForService(
							URI.create(HTTP_PROTOCOL + serviceURI.toString()), true,
							AUTHENTICATION_REQUEST_MSG);

					/*
					 * ...then save a second entry with HTTPS protocol (if the
					 * user has chosen to save the credentials)
					 */
					if (credentials != null && credentials.isShouldSave()) {
						credentialManager.addUsernameAndPasswordForService(credentials,
								URI.create(HTTPS_PROTOCOL + serviceURI.toString()));
					}
				}
			}

			if (credentials != null) {
				logger.info("Credentials obtained successfully");
				return new RESTActivityCredentials(credentials.getUsername(),
						credentials.getPasswordAsString());
			}
		} catch (Exception e) {
			logger.error(
					"Unexpected error while trying to obtain user's credential from CredentialManager",
					e);
		}

		// error or nothing was found
		logger.info("Credentials not found - the user must have refused to enter them.");
		return null;
	}

	/**
	 * This class encapsulates user's credentials that this CredentialsProvider
	 * can pass to Apache HttpClient.
	 *
	 * @author Sergejs Aleksejevs
	 */
	public class RESTActivityCredentials implements Credentials {
		// this seems to be the simplest existing standard implementation of
		// Principal interface
		private final JMXPrincipal user;
		private final String password;

		public RESTActivityCredentials(String username, String password) {
			this.user = new JMXPrincipal(username);
			this.password = password;
		}

		@Override
		public String getPassword() {
			return password;
		}

		@Override
		public Principal getUserPrincipal() {
			return user;
		}
	}
}
