#!/usr/bin/perl

# Generates members of o365 service in JSON format
#
#IMPORTANT: this Perun service is only prototype for common behavior
#           of pushing authorization data for o365 service

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

sub processMembers;

our $SERVICE_NAME = "o365";
our $PROTOCOL_VERSION = "3.0.0";
my $SCRIPT_VERSION = "3.0.1";

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

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_DISPLAY_NAME;         *A_USER_DISPLAY_NAME =         \'urn:perun:user:attribute-def:core:displayName';
our $A_USER_PHOTO;                *A_USER_PHOTO =                \'urn:perun:user:attribute-def:def:o365-userPhoto';
our $A_USER_FACILITY_LOGIN;       *A_USER_FACILITY_LOGIN =       \'urn:perun:user_facility:attribute-def:virt:login';
our $A_FACILITY_USAGE_LOCATION;   *A_FACILITY_USAGE_LOCATION =   \'urn:perun:facility:attribute-def:def:o365-usageLocation';
our $A_FACILITY_DOMAIN_NAME;      *A_FACILITY_DOMAIN_NAME =      \'urn:perun:facility:attribute-def:def:o365-domainName';
our $A_RESOURCE_ASSIGNED_LICENSE; *A_RESOURCE_ASSIGNED_LICENSE = \'urn:perun:resource:attribute-def:def:o365-assignedLicense';

our $USER_TYPE = 'member';

our $outputData = {value => []};
our $members = {};

our $usageLocation = $data->getFacilityAttributeValue( attrName => $A_FACILITY_USAGE_LOCATION );

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

	my $assignedLicense = $data->getResourceAttributeValue( resource => $resourceId, attrName => $A_RESOURCE_ASSIGNED_LICENSE );
	my $facilityDomain = $data->getFacilityAttributeValue( attrName => $A_FACILITY_DOMAIN_NAME );
	my @memberIds = $data->getMemberIdsForResource( resource => $resourceId ); 
	
	processMembers(\@memberIds, $assignedLicense, $facilityDomain );
}

# format of 1 line in photos.csv file:
# userPrincipalName,base64 photo encoding
my $filePhotos= $DIRECTORY . "photos.csv";
open FILE_PHOTOS, ">$filePhotos" or die "Cannot open $filePhotos: $! \n";

foreach my $mail (sort keys %{$members}) {
	my $member = $members->{$mail};

	if(defined $member->{'photo'}) {
		print FILE_PHOTOS "$mail,$member->{'photo'}", "\n";
	}

	push @{$outputData->{'value'}}, $member;
}

close(FILE_PHOTOS) or die "Cannot close $filePhotos: $! \n";

# format of 1 user in users.json file:
# {
# 	"accountEnabled":true,
# 	"assignedLicenses":["license1","license2"],
# 	"displayName":"James Bond",
# 	"givenName":"James",
# 	"mail":"james.bond@agent.com",
# 	"preferredName":"jamesb",
# 	"surname":"Bond",
# 	"usageLocation":"CZ",
# 	"userPrincipalName":"james.bond@agent.com",
# 	"userType":"member"
#	"photo":"base64string"
# }
my $fileUsers = $DIRECTORY . "users.json";
open FILE_USERS, ">$fileUsers" or die "Cannot open $fileUsers: $! \n";
print FILE_USERS JSON::XS->new->utf8->encode($outputData), "\n";
close(FILE_USERS) or die "Cannot close $fileUsers: $! \n";

perunServicesInit::finalize;

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

sub processMembers {
	#X my @membersData =  @{$_[0]};
	my $memberIds = $_[0];
	my $license =  $_[1];
	my $domainName = $_[2];

	foreach my $memberId (@{$memberIds}) {
		my $mail = $data->getUserFacilityAttributeValue( member => $memberId, attrName => $A_USER_FACILITY_LOGIN ) . '@' . $domainName;

		if($members->{$mail}) {
			push @{$members->{$mail}->{'assignedLicenses'}}, $license;
		} else {
			my @licenses = $license;
			my $member = {
				accountEnabled => \1,
				assignedLicenses => \@licenses,
				displayName => $data->getUserAttributeValue( member => $memberId, attrName => $A_USER_DISPLAY_NAME ),
				givenName => $data->getUserAttributeValue( member => $memberId, attrName => $A_USER_FIRST_NAME ),
				mail => $mail,
				surname => $data->getUserAttributeValue( member => $memberId, attrName => $A_USER_LAST_NAME ),
				usageLocation => $usageLocation,
				userPrincipalName => $mail,
				userType => $USER_TYPE,
				photo => $data->getUserAttributeValue( member => $memberId, attrName => $A_USER_PHOTO )
			};

			$members->{$mail} = $member;
		}
	}
}
