package info.bukova.isspst.services.users;

import info.bukova.isspst.data.Role;
import info.bukova.isspst.data.User;
import info.bukova.isspst.data.UsersAddress;

import javax.naming.NamingException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

/**
 * Pomocná třída pro import uživatele z LDAP serveru (nebo Active Directory) do databáze aplikace
 * 
 * @author pepa
 *
 */
public class LdapUserImporter {
	
	private UserService userService;
	private String allowedGroup;
	private final static Logger logger = LoggerFactory.getLogger(LdapUserImporter.class);
	
	public LdapUserImporter(UserService userService) {
		this.userService = userService;
	}
	
	public LdapUserImporter(UserService userService, String group) {
		this.userService = userService;
		this.allowedGroup = group;
	}
	
	/**
	 * Provede import uživatele z LDAP do aplikační databáze
	 * 
	 * @param login - login uživatele
	 * @param userData - objekt reprezentujízí data z LDAP
	 * @param defaultRole - role, která má být přidělena novému uživateli
	 */
	public void importUser(String login, DirContextOperations userData, Role defaultRole) {
		User user = new User();
		user.setUsername(login);
		user.addAuthority(defaultRole);
		
		if (allowedGroup != null && !allowedGroup.isEmpty()) {
			boolean isAllowed = false;
			
			for (Object atr : userData.getObjectAttributes("memberOf")) {
				if (atr.toString().startsWith("CN="+allowedGroup)) {
					isAllowed = true;
					break;
				}
			}
			
			if (!isAllowed) {
				throw new UsernameNotFoundException("User is not member of group '" + allowedGroup + "'");
			}
		}
		
		if (userData.attributeExists("givenName")) {
			try {
				user.setFirstName(userData.getAttributes().get("givenName").get().toString());
			} catch (NamingException e1) {
				logger.info("LDAP object has no 'givenName' attribute");
			}
		}
		if (userData.attributeExists("sn")) {
			try {
				user.setLastName(userData.getAttributes().get("sn").get().toString());
			} catch (NamingException e1) {
				logger.info("LDAP object has no 'sn' attribute");
			}
		}
		if (userData.attributeExists("mail")) {
			try {
				user.setEmail(userData.getAttributes().get("mail").get().toString());
				user.setNotify(true);
			} catch (NamingException e1) {
				logger.info("LDAP object has no 'mail' attribute");
			}
		}
		
		UsersAddress address = new UsersAddress();
		boolean hasAddress = false;
		
		if (userData.attributeExists("streetAddress")) {
			address.setStreet(userData.getStringAttribute("streetAddress"));
			hasAddress = true;
		}
		if (userData.attributeExists("l")) {
			address.setCity(userData.getStringAttribute("l"));
			hasAddress = true;
		}
		if (userData.attributeExists("postalCode")) {
			address.setZipCode(userData.getStringAttribute("postalCode"));
			hasAddress = true;
		}
		
		if (hasAddress) {
			user.setAddress(address);
		}
		
		user.setEnabled(true);
		
		userService.grantAdmin(); // povýšit práva pro toto vlákno
		userService.add(user);
		userService.removeAccess();
	}

}
