#!/usr/bin/perl
use strict;
use warnings;
use perunServicesInit;
use perunServicesUtils;
use Perun::Agent;
use JSON::XS;
use Tie::IxHash;

#forward declaration
sub processGroupData;

our $SERVICE_NAME = "pbsmon_users";
our $PROTOCOL_VERSION = "3.0.1";
my $SCRIPT_VERSION = "3.0.2";

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

#Constants
our $A_USER_NAME;           *A_USER_NAME =           \'urn:perun:user:attribute-def:core:displayName';
our $A_USER_ORG;            *A_USER_ORG =            \'urn:perun:user:attribute-def:def:organization';
our $A_USER_LOGIN;          *A_USER_LOGIN =          \'urn:perun:user_facility:attribute-def:virt:login';
our $A_USER_PUBLICATIONS;   *A_USER_PUBLICATIONS =   \'urn:perun:user:attribute-def:def:publications';
our $A_MEMBER_ORG;          *A_MEMBER_ORG =          \'urn:perun:member:attribute-def:def:organization';
our $A_MEMBER_STATUS;       *A_MEMBER_STATUS =       \'urn:perun:member:attribute-def:core:status';
our $A_MEMBER_EXPIRES;      *A_MEMBER_EXPIRES =      \'urn:perun:member:attribute-def:def:membershipExpiration';
our $A_GROUP_NAME;          *A_GROUP_NAME =          \'urn:perun:group:attribute-def:core:name';
our $A_GROUP_STATISTIC;     *A_GROUP_STATISTIC =     \'urn:perun:group:attribute-def:def:statisticGroup';
our $A_VO_NAME;             *A_VO_NAME =             \'urn:perun:vo:attribute-def:core:name';

my $attributesByLogin = {};

foreach my $resourceId ($data->getResourceIds) {

	my $voName = $data->getVoAttributeValue( vo => $data->getVoIdForResource( resource => $resourceId ), attrName => $A_VO_NAME );

	foreach my $groupId ($data->getGroupIdsForResource( resource => $resourceId )) {
		processGroupData $groupId, $resourceId, $voName, $attributesByLogin;
	}
}


my @users;
for my $login (sort keys %$attributesByLogin) {
	my $values = $attributesByLogin->{$login};
	push @users, \%$values;
}

my $struc = {};
$struc->{"users"} = \@users;

my $fileName = "$DIRECTORY/$SERVICE_NAME";
open FILE,">$fileName" or die "Cannot open $fileName: $! \n";
print FILE JSON::XS->new->utf8->pretty->canonical->encode($struc);
close FILE;

perunServicesInit::finalize;

############
### SUBS ###
############

sub processGroupData {
	my ($groupId, $resourceId, $voName, $attributesByLogin) = @_;

	for my $memberId ($data->getMemberIdsForResourceAndGroup( resource => $resourceId, group => $groupId )) {

		my $userLogin = $data->getUserFacilityAttributeValue( member => $memberId, attrName => $A_USER_LOGIN);
		
		unless($attributesByLogin->{$userLogin}) {
			$attributesByLogin->{$userLogin}->{"logname"} = $userLogin;
			$attributesByLogin->{$userLogin}->{"name"} = $data->getUserAttributeValue( member => $memberId, attrName => $A_USER_NAME);
			$attributesByLogin->{$userLogin}->{"org"} = $data->getUserAttributeValue( member => $memberId, attrName => $A_USER_ORG);
			$attributesByLogin->{$userLogin}->{"publications"} = $data->getUserAttributeValue( member => $memberId, attrName => $A_USER_PUBLICATIONS);
		}

		unless($attributesByLogin->{$userLogin}->{'vos'}->{$voName}) {
			$attributesByLogin->{$userLogin}->{'vos'}->{$voName}->{"org"} = $data->getMemberAttributeValue( member => $memberId, attrName => $A_MEMBER_ORG);
			$attributesByLogin->{$userLogin}->{'vos'}->{$voName}->{"expires"} = $data->getMemberAttributeValue( member => $memberId, attrName => $A_MEMBER_EXPIRES);
			$attributesByLogin->{$userLogin}->{'vos'}->{$voName}->{"status"} = $data->getMemberAttributeValue( member => $memberId, attrName => $A_MEMBER_STATUS);
		}

		#membership in groups
		unless($attributesByLogin->{$userLogin}->{'vos'}->{$voName}->{"groups"}) {
			my @groups = ( $data->getGroupAttributeValue(group => $groupId, attrName => $A_GROUP_NAME ) );
			$attributesByLogin->{$userLogin}->{'vos'}->{$voName}->{"groups"} = \@groups;
		} else {
			my @groups = uniqList( @{$attributesByLogin->{$userLogin}->{'vos'}->{$voName}->{"groups"}}, $data->getGroupAttributeValue(group => $groupId, attrName => $A_GROUP_NAME ) );
			@groups = sort @groups;
			$attributesByLogin->{$userLogin}->{'vos'}->{$voName}->{"groups"} = \@groups;
		}

		if($data->getGroupAttributeValue(group => $groupId, attrName => $A_GROUP_STATISTIC )) {
			$attributesByLogin->{$userLogin}->{'vos'}->{$voName}->{"statistic_groups"}->{$data->getGroupAttributeValue(group => $groupId, attrName => $A_GROUP_NAME )} = 1;
		}
	}
}
