#!/usr/bin/perl

use strict;
use warnings;
use perunServicesInit;
use perunServicesUtils;
use JSON::XS;
use utf8;

our $SERVICE_NAME     = "arcgis_licenses_mu";
our $PROTOCOL_VERSION = "3.0.1";

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

#Constants
our $A_USER_FIRST_NAME;             *A_USER_FIRST_NAME =             \'urn:perun:user:attribute-def:core:firstName';
our $A_USER_LAST_NAME;              *A_USER_LAST_NAME =              \'urn:perun:user:attribute-def:core:lastName';
our $A_USER_LOGIN;                  *A_USER_LOGIN =                  \'urn:perun:user_facility:attribute-def:virt:login';
our $A_MEMBER_STATUS;               *A_MEMBER_STATUS =               \'urn:perun:member:attribute-def:core:status';
our $A_RESOURCE_ARCGIS_ROLE;        *A_RESOURCE_ARCGIS_ROLE =        \'urn:perun:resource:attribute-def:def:arcGISRole';
our $A_RESOURCE_ARCGIS_AFFILIATION; *A_RESOURCE_ARCGIS_AFFILIATION = \'urn:perun:resource:attribute-def:def:arcGISIsActiveAffiliation';

#Headers
my $firstNameHeader = "firstName";
my $lastNameHeader = "lastName";
my $loginHeader = "UCO";
my $rolesHeader = "roles";
my $affiliationHeader = "isActive";
my $statusValid = 'VALID';

#Global data structure
my $usersWithRoles = {};

#start script
my $facilityId = $data->getFacilityId;

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

	my $roleOnResource = $data->getResourceAttributeValue( attrName => $A_RESOURCE_ARCGIS_ROLE, resource => $resourceId );
	my $isResourceActiveForAffiliation = $data->getResourceAttributeValue( attrName => $A_RESOURCE_ARCGIS_AFFILIATION, resource => $resourceId );

	#process all members on resource
	foreach my $memberId ($data->getMemberIdsForResource( resource => $resourceId )) {
		#skip not VALID members in VO
		my $statusInVo = $data->getMemberAttributeValue( attrName => $A_MEMBER_STATUS, member => $memberId );
		if( $statusInVo ne $statusValid ) { next; }

		my $UCO = $data->getUserFacilityAttributeValue( attrName => $A_USER_LOGIN, member => $memberId, facility => $facilityId );

		#if user not exists, create record for him first
		unless( $usersWithRoles->{$UCO} ) {

			my $firstName = $data->getUserAttributeValue( attrName => $A_USER_FIRST_NAME, member => $memberId );
			my $lastName = $data->getUserAttributeValue( attrName => $A_USER_LAST_NAME, member => $memberId );

			$usersWithRoles->{$UCO}->{$loginHeader} = $UCO;
			$usersWithRoles->{$UCO}->{$firstNameHeader} = $firstName;
			$usersWithRoles->{$UCO}->{$lastNameHeader} = $lastName;
			$usersWithRoles->{$UCO}->{$affiliationHeader} = 0;
		}

		#then add his roles and affiliation activity
		if( $roleOnResource ) {
			$usersWithRoles->{$UCO}->{$rolesHeader}->{$roleOnResource} = 1;
		}
		if( $isResourceActiveForAffiliation ) {
			$usersWithRoles->{$UCO}->{$affiliationHeader} = 1;
		}
	}
}

#prepare correct json structure
my @data;
for my $key (keys %{$usersWithRoles}) {
	my $userRecord = {};
	$userRecord->{$firstNameHeader} = $usersWithRoles->{$key}->{$firstNameHeader};
	$userRecord->{$lastNameHeader} = $usersWithRoles->{$key}->{$lastNameHeader};
	$userRecord->{$loginHeader} = $usersWithRoles->{$key}->{$loginHeader};
	my @roles = ();
	if($usersWithRoles->{$key}->{$rolesHeader}) {
		@roles = keys %{$usersWithRoles->{$key}->{$rolesHeader}};
	}
	$userRecord->{$rolesHeader} = \@roles;
	$userRecord->{$affiliationHeader} = $usersWithRoles->{$key}->{$affiliationHeader} ? JSON::XS::true : JSON::XS::false;
	push @data, $userRecord;
}

# order all entries by UCO
@data = sort { $a->{$loginHeader} <=> $b->{$loginHeader} } @data;

#print json to the file
my $file = "$DIRECTORY/$::SERVICE_NAME.json";
open FILE,">$file" or die "Cannot open $file: $! \n";
binmode(FILE);
print FILE JSON::XS->new->utf8->pretty->canonical->encode(\@data);
close (FILE) or die "Cannot close $file: $! \n";

perunServicesInit::finalize;
