package mx.nic.rdap.server.privacy;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class PrivacySettingsFactory {
	private static Map<String, PrivacySetting> singlePoolMap;

	private static Map<Set<String>, PrivacySetting> privacyCombinationPoolMap;

	private static Map<Set<String>, Set<String>> setCombinationPoolMap;

	private final static String ANY = "any";
	private final static String NONE = "none";
	private final static String OWNER = "owner";
	private final static String AUTHENTICATED = "authenticated";

	public static void initializePool(String... serverRoles) {
		singlePoolMap = new HashMap<>();

		singlePoolMap.put(ANY, new AnyPrivacySetting());
		singlePoolMap.put(NONE, new NonePrivacySetting());
		singlePoolMap.put(OWNER, new OwnerPrivacySetting());
		singlePoolMap.put(AUTHENTICATED, new AuthenticatedPrivacySetting());

		if (serverRoles != null && serverRoles.length > 0) {
			addRolesToSinglePoolMap(serverRoles);
		}

		privacyCombinationPoolMap = new HashMap<>();
		setCombinationPoolMap = new HashMap<>();
	}

	private static void addRolesToSinglePoolMap(String... roles) {
		for (String role : roles) {
			role = role.trim().toLowerCase();
			Set<String> set = new HashSet<>();
			set.add(role);
			set = Collections.unmodifiableSet(set);

			PrivacySetting privacySetting = new RolesPrivacySetting(false, set);
			singlePoolMap.put(role, privacySetting);
		}
	}

	public static PrivacySetting getSetForRoles(String... roles) {
		if (roles == null || roles.length <= 0) {
			throw new NullPointerException("Roles are null or empty.");
		}

		PrivacySetting privacySetting;
		if (roles.length == 1) {
			privacySetting = getSetForSingleValue(roles[0].trim().toLowerCase());
		} else {
			privacySetting = getSetForCombination(roles);
		}

		return privacySetting;
	}

	private static PrivacySetting getSetForSingleValue(String s) {
		return singlePoolMap.get(s);
	}

	private static PrivacySetting getSetForCombination(String... roles) {
		Set<String> set = new HashSet<>();
		for (String role : roles) {
			set.add(role.trim().toLowerCase());
		}

		Set<String> originalSet = setCombinationPoolMap.get(set);
		if (originalSet != null) {
			return privacyCombinationPoolMap.get(originalSet);
		}

		RolesPrivacySetting rolesPrivacySetting;
		if (set.contains(OWNER)) {
			Set<String> key = new HashSet<>(set);
			key = Collections.unmodifiableSet(key);
			setCombinationPoolMap.put(key, key);

			set.remove(OWNER);
			set = Collections.unmodifiableSet(set);
			rolesPrivacySetting = new RolesPrivacySetting(true, set);
			privacyCombinationPoolMap.put(key, rolesPrivacySetting);
		} else {
			set = Collections.unmodifiableSet(set);
			rolesPrivacySetting = new RolesPrivacySetting(false, set);
			privacyCombinationPoolMap.put(set, rolesPrivacySetting);
		}

		return rolesPrivacySetting;
	}
}

@@ -1673,32 +1673,39 @@
 g privacySetting
+ = null
 ;%0A%09%09if (roles.le
@@ -1720,32 +1720,22 @@
 1) %7B%0A%09%09%09
-privacySetting =
+return
  getSetF
@@ -1779,24 +1779,259 @@
 Case());%0A%09%09%7D
+%0A%0A%09%09Set%3CString%3E set = new HashSet%3C%3E();%0A%09%09for (String role : roles) %7B%0A%09%09%09set.add(role.trim().toLowerCase());%0A%09%09%7D%0A%0A%09%09if (set.size() == 1) %7B%0A%09%09%09for (String role : set) %7B%0A%09%09%09%09privacySetting = getSetForSingleValue(role);%0A%09%09%09%09break;%0A%09%09%09%7D%0A%09%09%7D
  else %7B%0A%09%09%09p
@@ -2067,21 +2067,19 @@
 ination(
-roles
+set
 );%0A%09%09%7D%0A%0A
@@ -2263,135 +2263,25 @@
 on(S
-tring... roles) %7B%0A%09%09Set%3CString%3E set = new HashSet%3C%3E();%0A%09%09for (String role : roles) %7B%0A%09%09%09set.add(role.trim().toLowerCase());%0A%09%09%7D
+et%3CString%3E set) %7B
 %0A%0A%09%09

Fix some use cases in privacySettingsFactory