package it.mice.voila.runtime.security;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;

/**
 * Created by IntelliJ IDEA.
 * User: zzy9v4
 * Date: 11-feb-2007
 * Time: 1.03.22
 * To change this template use File | Settings | File Templates.
 */
public class SecurityUtils {
    public static String defaultUserId = "ANONYMOUS";
	private static UserDetails defaultUserDetails = null;
	public static final Collection<GrantedAuthority> EMPTY_AUTHORITY_LIST = new ArrayList<GrantedAuthority>();
	public static final Set<String> EMPTY_ACL = new HashSet<String>();

    public void setDefaultUserId(String defaultUserId) {
        SecurityUtils.defaultUserId = defaultUserId;
    }

    /**
     * Method getCurrentUserId.
     * Restituisce la userId associata all'utente correntemente connesso.
     */
    public static String getCurrentUserId() {
        if (SecurityContextHolder.getContext().getAuthentication() != null) {
            try {
				return ((UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
			} catch (Exception e) {
	            return defaultUserId;
			}
        } else {
            return defaultUserId;
        }
    }

    public static boolean isAuthenticatedUser() {
    	return !getCurrentUserId().equals(defaultUserId);
    }

    public static boolean isUserInRoles(String...profiles) {
    	//String allProfs = ArrayUtils.
    	Iterator<? extends GrantedAuthority> i = getCurrentUserDetail().getAuthorities().iterator();
    	while (i.hasNext()) {
			GrantedAuthority grantedAuthority = (GrantedAuthority) i.next();
			String auth = grantedAuthority.getAuthority();
			for (int j = 0; j < profiles.length; j++) {
				if (auth.equalsIgnoreCase(profiles[j])) {
					return true;
				}
			}
		}
    	return false;
    }
    
    /**
     * Method getCurrentUserId.
     * Restituisce la userId associata all'utente correntemente connesso.
     */
    public static UserDetails getCurrentUserDetail() {
        if (SecurityContextHolder.getContext().getAuthentication() != null && SecurityContextHolder.getContext().getAuthentication().getPrincipal() instanceof UserDetails) {
            return (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        } else if (SecurityContextHolder.getContext().getAuthentication() != null && SecurityContextHolder.getContext().getAuthentication().getPrincipal() instanceof String) {
        	Collection<GrantedAuthority> auths = (Collection<GrantedAuthority>)SecurityContextHolder.getContext().getAuthentication().getAuthorities(); 
        	return new UserDetailImpl(SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString(), "", true, true, true, true, auths, null);
        } else {
        	if (defaultUserDetails == null) {
        		defaultUserDetails = new UserDetailImpl(defaultUserId, "", true, true, true, true, EMPTY_AUTHORITY_LIST, null);
        	}
            return defaultUserDetails;
        }
    }
    
    /**
     * Method getCurrentUserId.
     * Restituisce la userId associata all'utente correntemente connesso.
     */
    public static String getNominativoCurrentUser() {
    	UserDetailImpl userDetail = (UserDetailImpl)getCurrentUserDetail();
    	StringBuffer result = new StringBuffer();
    	if (userDetail.getFirstName() != null) {
    		result.append(userDetail.getFirstName());
    	}
    	if (userDetail.getLastName() != null) {
    		result.append(" ").append(userDetail.getLastName());
    	}
    	if (result.length() == 0) {
    		result.append(userDetail.getUsername());
    	}
    	return result.toString();
    }
    
	public static Set<String> extractAclQueries(String entityId, String queryId) {
		Object currentUser = SecurityUtils.getCurrentUserDetail();
		UserDetailImpl userDetailImpl;
		if (currentUser instanceof UserDetailImpl) {
			userDetailImpl = (UserDetailImpl)currentUser;
		} else {
			return EMPTY_ACL;
		}
		Set<String> queries = userDetailImpl.getAclQueryText(entityId + "." + queryId);
		queries.addAll(userDetailImpl.getAclQueryText(entityId));
		queries.addAll(userDetailImpl.getAclQueryText("*"));
		if (queries.contains("1=1") || queries.contains("true")) {
			return EMPTY_ACL;
		}
		return queries;
	}

}
