#!/usr/bin/perl

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

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

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

#Constants
our $A_FACILITY_GOOGLE_DOMAIN;            *A_FACILITY_GOOGLE_DOMAIN =             \'urn:perun:facility:attribute-def:def:googleGroupsDomain';
our $A_GROUP_RESOURCE_GOOGLE_GROUP_NAME;  *A_GROUP_RESOURCE_GOOGLE_GROUP_NAME =   \'urn:perun:group_resource:attribute-def:virt:googleGroupName';
our $A_USER_GOOGLE_NAMESPACE;             *A_USER_GOOGLE_NAMESPACE =              \'urn:perun:user:attribute-def:virt:logins-namespace:google';
our $A_USER_GOOGLE_MAILS;                 *A_USER_GOOGLE_MAILS =                  \'urn:perun:user:attribute-def:virt:mails-namespace:google';
our $A_RESOURCE_GOOGLE_TEAM_DRIVE;        *A_RESOURCE_GOOGLE_TEAM_DRIVE =         \'urn:perun:resource:attribute-def:def:googleTeamDriveName';

#Global data structures
our $groupStruc = {};
our $teamDriveStruc = {};

my $domainName = $data->getFacilityAttributeValue(attrName => $A_FACILITY_GOOGLE_DOMAIN);

foreach my $resourceId ($data->getResourceIds()) {
	my $googleTeamDriveName = $data->getResourceAttributeValue(attrName => $A_RESOURCE_GOOGLE_TEAM_DRIVE, resource => $resourceId);

	foreach my $groupId ($data->getGroupIdsForResource(resource => $resourceId)) {
		my $groupName = "";
		my $googleGroupName = $data->getGroupResourceAttributeValue(attrName => $A_GROUP_RESOURCE_GOOGLE_GROUP_NAME, group => $groupId, resource => $resourceId);
		if($googleGroupName) {
			$groupName = $googleGroupName . "@" . $domainName;
		}

		foreach my $memberId ($data->getMemberIdsForResourceAndGroup(resource => $resourceId, group => $groupId)) {
			my @logins = @{$data->getUserAttributeValue(attrName => $A_USER_GOOGLE_NAMESPACE, member => $memberId)};
			my @mails = @{$data->getUserAttributeValue(attrName => $A_USER_GOOGLE_MAILS, member => $memberId)};

			# skip users without google login, might happen, when user removes his UserExtSource
			# since google login is virtual attribute calculated from Google IdP UES.
			if (@logins) {
				if($groupName) {
					foreach my $member(@logins){
						unless(exists $groupStruc->{$groupName}->{$member}) {
							$groupStruc->{$groupName}->{$member} = {};
						}
					}
				}
				#process team drive for this user only if drive name has been set and google mails of this user has been obtained
				if($googleTeamDriveName && @mails) {
					foreach my $mail(@mails){
						#Add every google mail to team drive struc
						$teamDriveStruc->{$googleTeamDriveName}->{$mail} = 1;
					}
				}
			}
		}
	}
}

my $fileName = "$DIRECTORY/$::SERVICE_NAME" . "_groups.csv";
open FILE, ">$fileName" or die "Cannot open $fileName: $! \n";

# output of google_groups_groups.csv file:
# - groupName;groupDisplayName;id1,id2,id3 where
# groupName is 'group1@domain.name.com'
# groupDisplayName is optional and unused here
# id[x] is a list of group member identifiers

# output of google_groups_domain file:
# - there is only one line containing name of the domain

foreach my $group (sort keys %$groupStruc) {
	print FILE $group, ";;", join(',', sort keys %{$groupStruc->{$group}}), "\n";
}

close(FILE) or die "Cannot close $fileName: $! \n";

my $fileNameDomain = $DIRECTORY . "google_groups_domain";
open FILE, ">$fileNameDomain" or die "Cannot open $fileNameDomain: $! \n";
print FILE $domainName;
close(FILE) or die "Cannot close $fileNameDomain: $! \n";

#generate file with all team drives
my $fileTeamDrives = "$DIRECTORY/$::SERVICE_NAME" . "_team_drives.csv";
open FILE, ">$fileTeamDrives" or die "Cannot open $fileTeamDrives: $! \n";
foreach my $teamDriveName (sort keys %$teamDriveStruc) {
	print FILE $teamDriveName, "; ", join(',', sort keys %{$teamDriveStruc->{$teamDriveName}}), "\n";
}
close(FILE) or die "Cannot close $fileTeamDrives: $! \n";

perunServicesInit::finalize;
