class urn_perun_user_facility_attribute_def_virt_defaultUnixGID extends UserFacilityVirtualAttributesModuleAbstract implements UserFacilityVirtualAttributesModuleImplApi {

	@Override
	public Attribute getAttributeValue(PerunSessionImpl sess, User user, Facility facility, AttributeDefinition attributeDefinition) {
		Attribute attr = new Attribute(attributeDefinition);
		try {
			//first phase: if attribute UF:D:defaultUnixGID is set, it has top priority
			Attribute defaultUnixGID = sess.getPerunBl().getAttributesManagerBl().getAttribute(sess, facility, user, AttributesManager.NS_USER_FACILITY_ATTR_DEF + ":defaultUnixGID");
			if (defaultUnixGID.getValue() != null) {
				Utils.copyAttributeToVirtualAttributeWithValue(defaultUnixGID, attr);
				return attr;
			}
			//second phase: UF:D:defaultUnixGID is not set, module will select unix group name from preffered list
			String gidNamespace = (String) sess.getPerunBl().getAttributesManagerBl().getAttribute(sess, facility, AttributesManager.NS_FACILITY_ATTR_DEF + ":unixGID-namespace").getValue();
			if (gidNamespace == null) {
				return attr;
			}

			String groupNameNamespace = (String) sess.getPerunBl().getAttributesManagerBl().getAttribute(sess, facility, AttributesManager.NS_FACILITY_ATTR_DEF + ":unixGroupName-namespace").getValue();
			if (groupNameNamespace == null) {
				return attr;
			}

			Attribute userPreferredGroupNames = sess.getPerunBl().getAttributesManagerBl().getAttribute(sess, user, AttributesManager.NS_USER_ATTR_DEF + ":preferredUnixGroupName-namespace:" + groupNameNamespace);
			List<Resource> resources = sess.getPerunBl().getUsersManagerBl().getAllowedResources(sess, facility, user);
			if (userPreferredGroupNames.getValue() != null) {
				Map<String, Resource> resourcesWithName = new HashMap<>();
				for (Resource resource : resources) {
					String groupNameForTest = (String) sess.getPerunBl().getAttributesManagerBl().getAttribute(sess, resource, AttributesManager.NS_RESOURCE_ATTR_DEF + ":unixGroupName-namespace:" + groupNameNamespace).getValue();
					if (groupNameForTest != null) {
						resourcesWithName.put(groupNameForTest, resource);
					}
				}

				List<Member> userMembers = sess.getPerunBl().getMembersManagerBl().getMembersByUser(sess, user);
				Map<String, Group> groupsWithName = new HashMap<>();
				for (Resource resource : resources) {
					List<Group> groupsFromResource = sess.getPerunBl().getGroupsManagerBl().getAssignedGroupsToResource(sess, resource);
					for (Group group : groupsFromResource) {
						List<Member> groupMembers = sess.getPerunBl().getGroupsManagerBl().getGroupMembers(sess, group);
						groupMembers.retainAll(userMembers);
						if (!groupMembers.isEmpty()) {
							String groupNamesForTest = (String) sess.getPerunBl().getAttributesManagerBl().getAttribute(sess, group, AttributesManager.NS_GROUP_ATTR_DEF + ":unixGroupName-namespace:" + groupNameNamespace).getValue();
							if (groupNamesForTest != null) {
								groupsWithName.put(groupNamesForTest, group);
							}
						}
					}
				}

				for (String pGroupName : (List<String>) userPreferredGroupNames.getValue()) {
					if (resourcesWithName.containsKey(pGroupName)) {
						Resource resource = resourcesWithName.get(pGroupName);
						Attribute resourceUnixGID = sess.getPerunBl().getAttributesManagerBl().getAttribute(sess, resource, AttributesManager.NS_RESOURCE_ATTR_DEF + ":unixGID-namespace:" + gidNamespace);
						if(resourceUnixGID.getValue() != null) {
							Utils.copyAttributeToViAttributeWithoutValue(userPreferredGroupNames, attr);
							attr.setValue(resourceUnixGID.getValue());
							return attr;
						}
					}
					if (groupsWithName.containsKey(pGroupName)) {
						Group group = groupsWithName.get(pGroupName);
						Attribute groupUnixGID = sess.getPerunBl().getAttributesManagerBl().getAttribute(sess, group, AttributesManager.NS_GROUP_ATTR_DEF + ":unixGID-namespace:" + gidNamespace);
						if(groupUnixGID.getValue() != null) {
							Utils.copyAttributeToViAttributeWithoutValue(userPreferredGroupNames, attr);
							attr.setValue(groupUnixGID.getValue());
							return attr;
						}
					}
				}
			}
			//third phase: Preferred unix name is not on the facility and it is choosen basicDefaultGID
			Attribute basicGid = sess.getPerunBl().getAttributesManagerBl().getAttribute(sess, facility, user, AttributesManager.NS_USER_FACILITY_ATTR_DEF + ":basicDefaultGID");
			Utils.copyAttributeToVirtualAttributeWithValue(basicGid, attr);
			return attr;


		} catch (AttributeNotExistsException ex) {
			throw new ConsistencyErrorException(ex);
		} catch (WrongAttributeAssignmentException ex) {
			throw new InternalErrorException(ex);
		}
	}

}