package gov.va.med.ars.sec;

import java.net.URLDecoder;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * 
 * @author DNS   meinei
 *
 */
public class HacUserDetailsAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {

	/**
	 * logger
	 */
	//private static final Logger logger = Logger.getLogger(HacUserDetailsAuthenticationProvider.class.getName());
	
	static final Logger logger = Logger.getLogger("auditLogger");
	
	/**
	 * Injected by the security context
	 */
	@Autowired
	public AppAuthorization appAuthorization;
	
	@Override
	   protected UserDetails retrieveUser (String username, UsernamePasswordAuthenticationToken token) throws AuthenticationException
	   {
			AppUser appUser = new AppUser();
			String decryptedUsername = "";	
			HttpServletRequest request = request();		
			Object attrI = request.getParameter("i");
			Object attrS = request.getParameter("s").replace("%2b", "+");
			
			appUser.setName("Anonymous User");
			
			logger.trace("Make sure the session value wasn't altered.");
			logger.debug("Former session is" + attrS);
			logger.debug("Session is" + request.getSession());
			logger.debug("Session ID is" + request.getSession().getId());
			
			if(attrS != null && attrS.equals(request.getSession().getId())) {
				logger.trace("Build the username");
				if (attrI != null && username.equals("")) {
					try {
						username = URLDecoder.decode(attrI.toString(), "UTF-8");
						decryptedUsername = AESEncryption.decrypt(username);
					} catch (Exception e) {
						logger.error(e.getMessage());
					}
		        }				
			}
			
			logger.debug("Windows Logon ID is " + decryptedUsername);
			
			appAuthorization.setNtusername(decryptedUsername.toLowerCase());
	
			logger.trace("Authorize the user for the system");
			if (appAuthorization.isAuthorized()) {
				logger.trace("If authorized, build a profile");
				appUser = appAuthorization.getUser();
	
				logger.debug("username " + appUser.getName() + " is authorized");
			}
			

			return new User(
					appUser.getNtusername() + "::" + appUser.getName(),
					"nothing",
					true,
					true,
					true,
					true, 
					appUser.getAuthorities());
	   }

	@Override
	protected void additionalAuthenticationChecks(UserDetails userDetails,
			UsernamePasswordAuthenticationToken authentication)
			throws AuthenticationException { }
	
	/**
	 * Enables the HttpServletRequest to be accessible in the bean
	 * @return
	 */
	public static HttpServletRequest request() {
	    ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
	    return attr.getRequest();
	}
	
	/**
	 * Allows the security context to inject the AppAuthorization into the provider
	 * @param appAuthorization
	 */
	public void setAppAuthorization(AppAuthorization appAuthorization) {
		this.appAuthorization = appAuthorization;
	}
}
