package ca.corefacility.bioinformatics.irida.service.impl;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;

import ca.corefacility.bioinformatics.irida.exceptions.UserNotInSecurityContextException;
import ca.corefacility.bioinformatics.irida.model.RemoteAPI;
import ca.corefacility.bioinformatics.irida.model.RemoteAPIToken;
import ca.corefacility.bioinformatics.irida.model.User;
import ca.corefacility.bioinformatics.irida.repositories.RemoteApiTokenRepository;
import ca.corefacility.bioinformatics.irida.repositories.UserRepository;
import ca.corefacility.bioinformatics.irida.service.RemoteAPITokenService;

@Transactional
@Service
public class RemoteAPITokenServiceImpl implements RemoteAPITokenService {
	private RemoteApiTokenRepository tokenRepository;
	private UserRepository userRepository;

	@Autowired
	public RemoteAPITokenServiceImpl(RemoteApiTokenRepository tokenRepository, UserRepository userRepository) {
		super();
		this.tokenRepository = tokenRepository;
		this.userRepository = userRepository;
	}

	@Transactional
	@Override
	public void addToken(RemoteAPIToken token) {
		User user = userRepository.loadUserByUsername(getUserName());
		token.setUser(user);
		removeOldToken(token.getRemoteApi());
		tokenRepository.save(token);
	}

	@Override
	public RemoteAPIToken getToken(RemoteAPI remoteAPI) {
		User user = userRepository.loadUserByUsername(getUserName());

		return tokenRepository.readTokenForApiAndUser(remoteAPI, user);
	}

	/**
	 * Get the username of the currently logged in user.
	 * 
	 * @return String of the username of the currently logged in user
	 * @throws UserNotInSecurityContextException
	 *             if the currently logged in user could not be read from the
	 *             security context
	 */
	private String getUserName() throws UserNotInSecurityContextException {
		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
		if (authentication.getPrincipal() instanceof UserDetails) {
			UserDetails details = (UserDetails) authentication.getPrincipal();
			String username = details.getUsername();

			return username;
		}

		throw new UserNotInSecurityContextException(
				"The currently logged in user could not be read from the SecurityContextHolder");
	}

	/**
	 * Remove any old token for this user from the database
	 * 
	 * @param token
	 */
	@Transactional
	protected void removeOldToken(RemoteAPI api) {
		RemoteAPIToken oldToken = getToken(api);
		if (oldToken != null) {
			tokenRepository.delete(oldToken);
		}
	}
}

@@ -1000,17 +1000,16 @@
 nService
- 
 %7B%0A%09priva
@@ -1677,16 +1677,18 @@
 ame());%0A
+%09%09
 %0A%09%09retur
@@ -1744,24 +1744,26 @@
 I, user);%0A%09%7D
+%0A%09
 %0A%0A%09/**%0A%09 * G
@@ -1811,21 +1811,16 @@
 n user.%0A
-%09 * %0A
 %09 * @ret
@@ -1923,32 +1923,16 @@
 xception
-%0A%09 *            
  if the 
@@ -1986,24 +1986,8 @@
  the
-%0A%09 *            
  sec
@@ -2075,17 +2075,16 @@
 xception
- 
 %7B%0A%09%09Auth
@@ -2179,32 +2179,58 @@
  (authentication
+ != null && authentication
 .getPrincipal() 
@@ -2369,16 +2369,19 @@
 name();%0A
+%09%09%09
 %0A%09%09%09retu
@@ -2397,16 +2397,18 @@
 me;%0A%09%09%7D%0A
+%09%09
 %0A%09%09throw
@@ -2450,13 +2450,8 @@
 ion(
-%0A%09%09%09%09
 %22The
@@ -2531,16 +2531,17 @@
 r%22);%0A%09%7D%0A
+%09
 %0A%09/**%0A%09 
@@ -2599,13 +2599,8 @@
 ase%0A
-%09 * %0A
 %09 * 
@@ -2678,17 +2678,16 @@
 API api)
- 
 %7B%0A%09%09Remo
@@ -2727,17 +2727,16 @@
 i);%0A%09%09if
- 
 (oldToke
@@ -2745,17 +2745,16 @@
 != null)
- 
 %7B%0A%09%09%09tok

Ensuring the context returns a user