package info.bukova.isspst.services.users;

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

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.openid.OpenIDAttribute;
import org.springframework.security.openid.OpenIDAuthenticationToken;

public class GmailUserService implements AuthenticationUserDetailsService<OpenIDAuthenticationToken> {

	private static final Logger logger = LoggerFactory.getLogger(GmailUserService.class); 
	
	private UserService userService;
	private RoleService roleService;
	private String restrictDomain;
	
	public GmailUserService(UserService userService, RoleService roleService) {
		this.userService = userService;
		this.roleService = roleService;
	}
	
	@Override
	public UserDetails loadUserDetails(OpenIDAuthenticationToken token)
			throws UsernameNotFoundException {
		
		String email = null;
		String firstName = null;
		String lastName = null;
		List<OpenIDAttribute> attributes = token.getAttributes();

		for (OpenIDAttribute attribute : attributes) {
			if (attribute.getName().equals("email")) {
				email = attribute.getValues().get(0);
			}
			if (attribute.getName().equals("firstName")) {
				firstName = attribute.getValues().get(0);
			}
			if (attribute.getName().equals("lastName")) {
				lastName = attribute.getValues().get(0);
			}
		}
		
		String userAndDomain[] = email.split("@");
		String username = userAndDomain[0];
		String domain = userAndDomain[1];
		
		if (restrictDomain != null && !restrictDomain.isEmpty() && !restrictDomain.equals(domain)) {
			logger.warn("Try to login from foreign domain");
			
			throw new UsernameNotFoundException("Email from foreign domain");
		}
		
		UserDetails user;
		
		try {
			user = userService.loadUserByUsername(username);
		} catch (UsernameNotFoundException e) {
			logger.info("Username not found in database. Creating one");
			
			User usr = new User();
			usr.setUsername(username);
			usr.setFirstName(firstName);
			usr.setLastName(lastName);
			usr.setEmail(email);
			usr.setEnabled(true);
			usr.setNotify(true);
			
			Role role = roleService.getRoleByAuthority(Constants.ROLE_USER);
			usr.addAuthority(role);
			
			userService.grantAdmin();
			userService.add(usr);
			userService.removeAccess();
			
			user = userService.loadUserByUsername(username);
		}
		
		return user;
	}

	public void setRestrictDomain(String restrictDomain) {
		this.restrictDomain = restrictDomain;
	}

}
