package gov.va.vinci.dart.usr;

import gov.va.vinci.dart.service.DartObjectFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

/** Custom Authenticator for use with Spring Security
 *
 */
public class CustomAuthenticator implements AuthenticationProvider {
	private static Log log = LogFactory.getLog(CustomAuthenticator.class);
	
	@Override
	public Authentication authenticate(Authentication authentication)
			throws AuthenticationException {
		
		if ((authentication instanceof UsernamePasswordAuthenticationToken) == false) {
			return null;
		}
		
		UsernamePasswordAuthenticationToken token = 
				(UsernamePasswordAuthenticationToken)authentication;

		// token.getName() contains the j_username submitted form value
		// token.getCredentials() contains the j_password submitted form value 
		
		UserManager userManager = DartObjectFactory.getInstance().getUserManager();

		CustomAuthentication result = new CustomAuthentication(token.getName(), token.getAuthorities(), token.getCredentials(), token.getDetails(), token.getPrincipal());

		try {
			userManager.login(result);
		}
		catch (Exception e) {
			log.error("Error authenticating user: " + e.getMessage());
			throw new UsernameNotFoundException("Error authenticating user.", e);
		}

		System.out.println("User " + token.getName() + " logged in.");
		
		result.grant(new SimpleGrantedAuthority("ROLE_USER"));  // go with this simple authority for the Spring Security url interceptor
		result.setAuthenticated(true);
		
		return result;
	}
	
	@Override
	public boolean supports(Class<?> authentication) {
		
		// return true if this class can authenticate that type of authentication object

		if (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication) == true) {
			return true;
		}
		
		return false;
	}

}

