#!/usr/bin/perl

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

local $::SERVICE_NAME = "pithia_portal";
local $::PROTOCOL_VERSION = "2.0.0";
my $SCRIPT_VERSION = "2.0.0";

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

#Constants
our $A_GROUP_NAME;                *A_GROUP_NAME =        \'urn:perun:group:attribute-def:core:name';
our $A_USER_D_NAME;               *A_USER_D_NAME =       \'urn:perun:user:attribute-def:core:displayName';
our $A_USER_EMAIL;                *A_USER_EMAIL =        \'urn:perun:user:attribute-def:def:preferredMail';
our $A_USER_EPPNS;                *A_USER_EPPNS =        \'urn:perun:user:attribute-def:virt:eduPersonPrincipalNames';
our $A_MEMBER_STATUS;             *A_MEMBER_STATUS =     \'urn:perun:member:attribute-def:core:status';

# $outputData->{"organizations"} = @organizations
# $outputData->{"users"} = @users
my $outputData;

my $organizations;
my $users;

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

	# collect all users
	foreach my $memberId ($data->getMemberIdsForResource(resource => $resourceId)) {

		my $userId = $data->getUserIdForMember(member => $memberId);

		my $eppns = $data->getUserAttributeValue(member => $memberId, attrName => $A_USER_EPPNS);
		my $edu_person_unique_id = undef;
		foreach my $eppn (@$eppns) {
			if ($eppn =~ m/^[^@]+\@egi.eu/) {
				if (!defined $edu_person_unique_id) {
					$edu_person_unique_id = $eppn;
				} else {
					die("User $userId has multiple EGI identities: $eppn and $edu_person_unique_id");
				}
			}
		}

		# skip users without EGI identity!!
		next if !defined $edu_person_unique_id;

		my $user;
		$user->{'edu_person_unique_id'} = $edu_person_unique_id;
		$user->{'name'} = $data->getUserAttributeValue(member => $memberId, attrName => $A_USER_D_NAME) || "";
		$user->{'email'} = $data->getUserAttributeValue(member => $memberId, attrName => $A_USER_EMAIL) || "";

		my $status = $data->getMemberAttributeValue(member => $memberId, attrName => $A_MEMBER_STATUS);
		if ($status eq "VALID") {
			$user->{'status'} = 'ACTIVE';
		} else {
			$user->{'status'} = 'INACTIVE';
		}

		$users->{$userId} = $user;

	}

	# collect all organizations
	foreach my $groupId ($data->getGroupIdsForResource(resource => $resourceId)) {

		my $groupName = $data->getGroupAttributeValue(group => $groupId, attrName => $A_GROUP_NAME);

		# skip top-level hierarchy group assigned to their single facility
		next if ($groupName eq "organizations");

		# process only first level child groups
		if ($groupName =~ m/^organizations:([^:]+)$/ ) {
			my $group;
			$group->{'name'} = $1;
			$organizations->{$groupName} = $group;
		}

	}

	# fill all organizations with members data
	foreach my $groupId ($data->getGroupIdsForResource(resource => $resourceId)) {

		my $groupName = $data->getGroupAttributeValue(group => $groupId, attrName => $A_GROUP_NAME);

		# skip top-level hierarchy group assigned to their single facility
		next if ($groupName eq "organizations");

		# skip all first level child groups
		#unless ($groupName =~ m/^organizations:[^:]+:(.)+/ ) {
		#	next;
		#}

		if ($groupName =~ m/^organizations:[^:]+:members$/ ) {
			my @members = ();
			foreach my $memberId ($data->getMemberIdsForResourceAndGroup(resource => $resourceId, group => $groupId)) {
				my $userId = $data->getUserIdForMember(member => $memberId);
				push(@members, $users->{$userId}->{'edu_person_unique_id'});
			}
			@members = sort(@members);

			foreach my $orgName (sort keys %$organizations) {
				if ($groupName eq "$orgName:members")  {
					$organizations->{$orgName}->{'members'} = \@members;
					next;
				}
			}

		}

		if ($groupName =~ m/^organizations:[^:]+:admins$/ ) {
			my @admins = ();
			foreach my $memberId ($data->getMemberIdsForResourceAndGroup(resource => $resourceId, group => $groupId)) {
				my $userId = $data->getUserIdForMember(member => $memberId);
				push(@admins, $users->{$userId}->{'edu_person_unique_id'});
			}
			@admins = sort(@admins);

			foreach my $orgName (sort keys %$organizations) {
				if ($groupName eq "$orgName:admins")  {
					$organizations->{$orgName}->{'admins'} = \@admins;
					next;
				}
			}

		}

	}

}

my @printOrganizations;
foreach my $orgName (sort keys %$organizations) {
	push(@printOrganizations, $organizations->{$orgName});
}

my @printUsers;
foreach my $userId (sort keys %$users) {
	push(@printUsers, $users->{$userId});
}

$outputData->{"organizations"} = \@printOrganizations;
$outputData->{"users"} = \@printUsers;

# PRINT DATA TO JSON 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($outputData);
close (FILE) or die "Cannot close $file: $! \n";

perunServicesInit::finalize;
