#!/usr/bin/perl

use strict;
use warnings;
use perunServicesInit;
use perunServicesUtils;

#forward declaration
sub processGroupData;
sub processMembersData;
sub processResourceData;

our $SERVICE_NAME = "afs_group";
our $PROTOCOL_VERSION = "3.0.0";
my $SCRIPT_VERSION = "3.0.2";

perunServicesInit::init;
my $DIRECTORY = perunServicesInit::getDirectory;
my $data = perunServicesInit::getHashedDataWithGroups;

#Constants
our $A_GR_AFS_GROUP_NAME;         *A_GR_AFS_GROUP_NAME =      \'urn:perun:group_resource:attribute-def:def:afsGroupName';
our $A_USER_KERBEROS_LOGINS;      *A_USER_KERBEROS_LOGINS =   \'urn:perun:user:attribute-def:virt:kerberosLogins';
our $A_USER_FACILITY_LOGIN;       *A_USER_FACILITY_LOGIN =    \'urn:perun:user_facility:attribute-def:virt:login';
our $A_R_DEFAULT_USERS_REALM;     *A_R_DEFAULT_USERS_REALM =  \'urn:perun:resource:attribute-def:def:afsDefaultUsersRealm';
our $A_MEMBER_STATUS;             *A_MEMBER_STATUS =          \'urn:perun:member:attribute-def:core:status';

our $STATUS_VALID;                *STATUS_VALID =             \'VALID';

#Global data structure
our $groupStruc = {};     #$groupStruc->{$groupName}->{$login} = 1;

foreach my $resourceId ($data->getResourceIds()) {
	foreach my $groupId ($data->getGroupIdsForResource(resource => $resourceId)) {
		processGroupData $groupId, $resourceId, $data->getResourceAttributeValue(attrName => $A_R_DEFAULT_USERS_REALM, resource => $resourceId);
	}
}

my $groupsDirName = "$DIRECTORY/groups";
mkdir $groupsDirName or die "Cannot mkdir $groupsDirName: $!";

foreach my $groupName (keys %$groupStruc) {
	my $fileName = $groupsDirName . "/" . $groupName;
	open FILE,">$fileName" or die "Cannot open $fileName: $! \n";
	my @groupMembers = sort keys %{$groupStruc->{$groupName}};
	print FILE join "\n", @groupMembers;
	close FILE or die "Cannot close file: $!";
}
perunServicesInit::finalize;

##############################################################################
#   Only subs definitions down there
##############################################################################

sub processGroupData {
	my ($groupId, $resourceId, $defaultUserRealm) = @_;
	my @memberIds = $data->getMemberIdsForResourceAndGroup(resource => $resourceId, group => $groupId);

	my $groupName = $data->getGroupResourceAttributeValue(attrName => $A_GR_AFS_GROUP_NAME, group => $groupId, resource => $resourceId);

	if(defined $groupName) {
		processMembersData \@memberIds, $groupName, $defaultUserRealm;
	}
}

# input: (reference to member ids array, groupName, defaultUserRealm)
# stores memers logins into $groupStruc structure
sub processMembersData {
	my ($memberIdsRef, $groupName, $defaultUserRealm) = @_;
	for my $memberId (@$memberIdsRef) {

		# skip members expired in VO
		next unless ($STATUS_VALID eq $data->getMemberAttributeValue(attrName => $A_MEMBER_STATUS, member => $memberId));

		my $login = $data->getUserFacilityAttributeValue(attrName => $A_USER_FACILITY_LOGIN, member => $memberId) . '@' . $defaultUserRealm;
		$groupStruc->{$groupName}->{$login} = 1;

	}
}
