package gov.va.med.mpn.auth.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

import com.agilex.healthcare.mobilehealthplatform.domain.MdwsKey;
import com.agilex.healthcare.mobilehealthplatform.domain.MdwsKeys;
import com.agilex.healthcare.mobilehealthplatform.domain.MhpUser;
import com.agilex.healthcare.mobilehealthplatform.security.AppUser;



/**
 * The Class AuthUtils. This utility class updates the Spring Application Granted authorities
 * by adding ROLE_PREFIX to the MDWS keys found in the MdwsInfo
 * of the MhpUser.  Also provides helper methods for accessing values
 * within the spring security principal.
 * <p>
 * <A HREF="http://www.hp.com"> Hewlett-Packard Enterprise Services</A>
 * </p>
 * 
 * @author <a href="mailto:david.aar.lucas@hp.com">Aaron Lucas</a> 
 */
public class AuthUtils {
	
	/** The Constant logger. */
	private final static Logger logger = LoggerFactory.getLogger(AuthUtils.class);
	
	/** The Constant ROLE_PREFIX. */
	private static final String ROLE_PREFIX = "ROLE_"; 
	
	/** The Constant REGEX_MPN_ROLE. */
	public static final String REGEX_MPN_ROLE = "ROLE_MPN.*";
	
	/** The Constant REGEX_MPNADMIN_ROLE. */
	public static final String REGEX_MPNADMIN_ROLE = "ROLE_MPN.*_ADMIN";
	
	/** The Constant REGEX_MPNUSER_ROLE. */
	public static final String REGEX_MPNUSER_ROLE = "ROLE_MPN.*_USER";
	
	/**
	 * Sets the spring security mae roles from mdws keys.
	 *
	 * @param keys the keys
	 * @return the list
	 */
	protected static List<GrantedAuthority> setSpringSecurityMAERolesFromMdwsKeys(MdwsKeys keys)
	{
		List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
		
		for(MdwsKey key : keys.getMdwsKey())
		{
			authorities.add(new SimpleGrantedAuthority(ROLE_PREFIX + key.getName()));
			
		}
		return authorities;
	}
	
	/**
	 * Update app user roles.
	 *
	 * @param mhp the mhp
	 * @return the username password authentication token
	 */
	public static UsernamePasswordAuthenticationToken updateAppUserRoles(AppUser mhp)
	{
		String user = mhp.getUsername();
		String pwd = mhp.getPassword();
		MhpUser orig = mhp.getMhpUser();
		List<GrantedAuthority> origAuthorities = new ArrayList<GrantedAuthority>();
		for(GrantedAuthority auth:mhp.getAuthorities())
		{
			origAuthorities.add(auth);
		}
		origAuthorities.addAll(setSpringSecurityMAERolesFromMdwsKeys(mhp.getMhpUser().getMdwsInfo().getKeys()));
		AppUser updatedUser = new AppUser(user, pwd, origAuthorities, orig);
		return new UsernamePasswordAuthenticationToken(updatedUser, null, origAuthorities);
	}
	
	/**
	 * Gets the authorities list.
	 *
	 * @param auth the auth
	 * @return the authorities list
	 */
	public static List<String> getAuthoritiesList(Authentication auth)
	{
		List<String> auths = new ArrayList<String>();
		for(GrantedAuthority a:auth.getAuthorities())
		{
			auths.add(a.getAuthority());
		}
		return auths;
	}
	
	/**
	 * Match authority.
	 *
	 * @param auth the auth
	 * @param patternToMatch the pattern to match
	 * @return true, if successful
	 */
	public static boolean matchAuthority(Authentication auth, String patternToMatch)
	{
		for(String s: getAuthoritiesList(auth))
		{
		 if(Pattern.matches(patternToMatch, s)) {
			 logger.debug("{} : {}", patternToMatch, s);
		     return true;
		  }
		}
		return false;
	}
	
	/**
	 * Gets the user display name.
	 *
	 * @param user the user
	 * @return the user display name
	 */
	public static String getUserDisplayName(AppUser user)
	{
		return user.getMhpUser().getDisplayName();
	}
	
	/**
	 * Gets the user station number.
	 *
	 * @param user the user
	 * @return the user station number
	 */
	public static String getUserStation(AppUser user)
	{
		return user.getMhpUser().getVistaLocation();
	}
	
	/**
	 * Gets the username.
	 *
	 * @param user the user
	 * @return the username
	 */
	public static String getUsername(AppUser user)
	{ 
		return user.getMhpUser().getUserIdentifier().toString();
	}

}
