/*
 */
package org.taverna.server.master.identity;

import static java.util.Collections.synchronizedMap;
import static org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes;
import static org.taverna.server.master.common.Roles.SELF;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import javax.annotation.Nonnull;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.taverna.server.master.exceptions.UnknownRunException;
import org.taverna.server.master.interfaces.LocalIdentityMapper;
import org.taverna.server.master.interfaces.RunStore;
import org.taverna.server.master.utils.CallTimeLogger.PerfLogged;
import org.taverna.server.master.utils.UsernamePrincipal;
import org.taverna.server.master.worker.RunDatabaseDAO;

/**
 * A special authentication provider that allows a workflow to authenticate to
 * itself. This is used to allow the workflow to publish to its own interaction
 * feed.
 * 
 * @author Donal Fellows
 */
public class WorkflowInternalAuthProvider extends
		AbstractUserDetailsAuthenticationProvider {
	private Log log = LogFactory.getLog("Taverna.Server.UserDB");
	private static final boolean logDecisions = true;
	public static final String PREFIX = "wfrun_";
	private RunDatabaseDAO dao;
	private Map<String, String> cache;

	@Required
	public void setDao(RunDatabaseDAO dao) {
		this.dao = dao;
	}

	@Required
	@SuppressWarnings("serial")
	public void setCacheBound(final int bound) {
		cache = synchronizedMap(new LinkedHashMap<String, String>() {
			@Override
			protected boolean removeEldestEntry(Map.Entry<String, String> eldest) {
				return size() > bound;
			}
		});
	}

	public void setAuthorizedAddresses(String[] addresses) {
		authorizedAddresses = new HashSet<>(localAddresses);
		for (String s : addresses)
			authorizedAddresses.add(s);
	}

	@PostConstruct
	public void logConfig() {
		log.info("authorized addresses for automatic access: "
				+ authorizedAddresses);
	}

	@PreDestroy
	void closeLog() {
		log = null;
	}

	private final Set<String> localAddresses = new HashSet<>();
	private Set<String> authorizedAddresses;
	{
		localAddresses.add("127.0.0.1"); // IPv4
		localAddresses.add("::1"); // IPv6
		try {
			InetAddress addr = InetAddress.getLocalHost();
			if (!addr.isLoopbackAddress())
				localAddresses.add(addr.getHostAddress());
		} catch (UnknownHostException e) {
			// Ignore the exception
		}
		authorizedAddresses = new HashSet<>(localAddresses);
	}

	/**
	 * Check that the authentication request is actually valid for the given
	 * user record.
	 * 
	 * @param userRecord
	 *            as retrieved from the
	 *            {@link #retrieveUser(String, UsernamePasswordAuthenticationToken)}
	 *            or <code>UserCache</code>
	 * @param principal
	 *            the principal that is trying to authenticate (and that we're
	 *            trying to bind)
	 * @param credentials
	 *            the credentials (e.g., password) presented by the principal
	 * 
	 * @throws AuthenticationException
	 *             AuthenticationException if the credentials could not be
	 *             validated (generally a <code>BadCredentialsException</code>,
	 *             an <code>AuthenticationServiceException</code>)
	 * @throws Exception
	 *             If something goes wrong. Will be logged and converted to a
	 *             generic AuthenticationException.
	 */
	protected void additionalAuthenticationChecks(UserDetails userRecord,
			@Nonnull Object principal, @Nonnull Object credentials)
			throws Exception {
		@Nonnull
		HttpServletRequest req = ((ServletRequestAttributes) currentRequestAttributes())
				.getRequest();

		// Are we coming from a "local" address?
		if (!req.getLocalAddr().equals(req.getRemoteAddr())
				&& !authorizedAddresses.contains(req.getRemoteAddr())) {
			if (logDecisions)
				log.info("attempt to use workflow magic token from untrusted address:"
						+ " token="
						+ userRecord.getUsername()
						+ ", address="
						+ req.getRemoteAddr());
			throw new BadCredentialsException("bad login token");
		}

		// Does the password match?
		if (!credentials.equals(userRecord.getPassword())) {
			if (logDecisions)
				log.info("workflow magic token is untrusted due to password mismatch:"
						+ " wanted="
						+ userRecord.getPassword()
						+ ", got="
						+ credentials);
			throw new BadCredentialsException("bad login token");
		}

		if (logDecisions)
			log.info("granted role " + SELF + " to user "
					+ userRecord.getUsername());
	}

	/**
	 * Retrieve the <code>UserDetails</code> from the relevant store, with the
	 * option of throwing an <code>AuthenticationException</code> immediately if
	 * the presented credentials are incorrect (this is especially useful if it
	 * is necessary to bind to a resource as the user in order to obtain or
	 * generate a <code>UserDetails</code>).
	 * 
	 * @param username
	 *            The username to retrieve
	 * @param details
	 *            The details from the authentication request.
	 * @see #retrieveUser(String,UsernamePasswordAuthenticationToken)
	 * @return the user information (never <code>null</code> - instead an
	 *         exception should the thrown)
	 * @throws AuthenticationException
	 *             if the credentials could not be validated (generally a
	 *             <code>BadCredentialsException</code>, an
	 *             <code>AuthenticationServiceException</code> or
	 *             <code>UsernameNotFoundException</code>)
	 * @throws Exception
	 *             If something goes wrong. It will be logged and converted into
	 *             a general AuthenticationException.
	 */
	@Nonnull
	protected UserDetails retrieveUser(String username, Object details)
			throws Exception {
		if (details == null || !(details instanceof WebAuthenticationDetails))
			throw new UsernameNotFoundException("context unsupported");
		if (!username.startsWith(PREFIX))
			throw new UsernameNotFoundException(
					"unsupported username for this provider");
		if (logDecisions)
			log.info("request for auth for user " + username);
		String wfid = username.substring(PREFIX.length());
		String securityToken;
		try {
			securityToken = cache.get(wfid);
			if (securityToken == null) {
				securityToken = dao.getSecurityToken(wfid);
				if (securityToken == null)
					throw new UsernameNotFoundException("no such user");
				cache.put(wfid, securityToken);
			}
		} catch (NullPointerException npe) {
			throw new UsernameNotFoundException("no such user");
		}
		return new User(username, securityToken, true, true, true, true,
				Arrays.asList(new LiteralGrantedAuthority(SELF),
						new WorkflowSelfAuthority(wfid)));
	}

	@Override
	@PerfLogged
	protected final void additionalAuthenticationChecks(UserDetails userRecord,
			UsernamePasswordAuthenticationToken token) {
		try {
			additionalAuthenticationChecks(userRecord, token.getPrincipal(),
					token.getCredentials());
		} catch (AuthenticationException e) {
			throw e;
		} catch (Exception e) {
			log.warn("unexpected failure in authentication", e);
			throw new AuthenticationServiceException(
					"unexpected failure in authentication", e);
		}
	}

	@Override
	@Nonnull
	@PerfLogged
	protected final UserDetails retrieveUser(String username,
			UsernamePasswordAuthenticationToken token) {
		try {
			return retrieveUser(username, token.getDetails());
		} catch (AuthenticationException e) {
			throw e;
		} catch (Exception e) {
			log.warn("unexpected failure in authentication", e);
			throw new AuthenticationServiceException(
					"unexpected failure in authentication", e);
		}
	}

	@SuppressWarnings("serial")
	public static class WorkflowSelfAuthority extends LiteralGrantedAuthority {
		public WorkflowSelfAuthority(String wfid) {
			super(wfid);
		}

		public String getWorkflowID() {
			return getAuthority();
		}

		@Override
		public String toString() {
			return "WORKFLOW(" + getAuthority() + ")";
		}
	}

	public static class WorkflowSelfIDMapper implements LocalIdentityMapper {
		private Log log = LogFactory.getLog("Taverna.Server.UserDB");
		private RunStore runStore;

		@PreDestroy
		void closeLog() {
			log = null;
		}

		@Required
		public void setRunStore(RunStore runStore) {
			this.runStore = runStore;
		}

		private String getUsernameForSelfAccess(WorkflowSelfAuthority authority)
				throws UnknownRunException {
			return runStore.getRun(authority.getWorkflowID())
					.getSecurityContext().getOwner().getName();
		}

		@Override
		@PerfLogged
		public String getUsernameForPrincipal(UsernamePrincipal user) {
			Authentication auth = SecurityContextHolder.getContext()
					.getAuthentication();
			if (auth == null || !auth.isAuthenticated())
				return null;
			try {
				for (GrantedAuthority authority : auth.getAuthorities())
					if (authority instanceof WorkflowSelfAuthority)
						return getUsernameForSelfAccess((WorkflowSelfAuthority) authority);
			} catch (UnknownRunException e) {
				log.warn("workflow run disappeared during computation of workflow map identity");
			}
			return null;
		}
	}
}
