package eu.dnetlib.organizations.controller;

import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser;
import org.springframework.security.oauth2.core.oidc.user.OidcUser;

public class UserInfo {

	private String name;
	private UserRole role;

	public UserInfo() {
		this.name = "anonymous";
		this.role = UserRole.NOT_AUTHORIZED;
	}

	public UserInfo(final String name, final UserRole role) {
		this.name = name;
		this.role = role;
	}

	public String getName() {
		return name;
	}

	public void setName(final String name) {
		this.name = name;
	}

	public UserRole getRole() {
		return role;
	}

	public void setRole(final UserRole role) {
		this.role = role;
	}

	public static UserInfo generate(final Authentication authentication) {
		return new UserInfo(getEmail(authentication), findRole(authentication));
	}

	public static UserRole findRole(final Authentication authentication) {

		return authentication.getAuthorities()
			.stream()
			.map(GrantedAuthority::getAuthority)
			.map(s -> StringUtils.substringAfter(s, "ROLE_OPENORGS_"))
			.filter(s -> EnumUtils.isValidEnum(UserRole.class, s))
			.map(UserRole::valueOf)
			.findFirst()
			.orElseGet(() -> UserRole.NOT_AUTHORIZED);
	}

	public static boolean isSuperAdmin(final Authentication authentication) {
		for (final GrantedAuthority aut : authentication.getAuthorities()) {
			if (aut.getAuthority().equals("ROLE_OPENORGS_" + UserRole.ADMIN)) { return true; }
		}
		return false;
	}

	public static boolean isNationalAdmin(final Authentication authentication) {
		for (final GrantedAuthority aut : authentication.getAuthorities()) {
			if (aut.getAuthority().equals("ROLE_OPENORGS_" + UserRole.NATIONAL_ADMIN)) { return true; }
		}
		return false;
	}

	public static boolean isSimpleUser(final Authentication authentication) {
		for (final GrantedAuthority aut : authentication.getAuthorities()) {
			if (aut.getAuthority().equals("ROLE_OPENORGS_" + UserRole.USER)) { return true; }
		}
		return false;
	}

	public static boolean isPending(final Authentication authentication) {
		for (final GrantedAuthority aut : authentication.getAuthorities()) {
			if (aut.getAuthority().equals("ROLE_OPENORGS_" + UserRole.PENDING)) { return true; }
		}
		return false;
	}

	public static boolean isNotAuthorized(final Authentication authentication) {
		for (final GrantedAuthority aut : authentication.getAuthorities()) {
			if (aut.getAuthority().equals("ROLE_OPENORGS_" + UserRole.NOT_AUTHORIZED)) { return true; }
		}
		return false;
	}

	public static String getEmail(final Authentication authentication) {
		final Object user = authentication.getPrincipal();
		return user instanceof DefaultOidcUser ? getEmail((DefaultOidcUser) user) : authentication.getName();
	}

	public static String getEmail(final OidcUser user) {
		return user.getEmail();
	}

	public static String getFullname(final Authentication authentication) {
		final Object user = authentication.getPrincipal();
		return user instanceof DefaultOidcUser ? getFullname((DefaultOidcUser) user) : "unknown";
	}

	public static String getFullname(final OidcUser user) {
		return user.getFullName();
	}

	public static String getOrganization(final Authentication authentication) {
		final Object user = authentication.getPrincipal();
		return user instanceof DefaultOidcUser ? getOrganization((DefaultOidcUser) user) : "unknown";
	}

	public static String getOrganization(final OidcUser user) {
		return StringUtils.firstNonBlank(user.getAttribute("organization"), user.getAttribute("affiliation"));
	}

}
