#!/usr/bin/perl
use feature "switch";
use strict;
use warnings;
use perunServicesInit;
use perunServicesUtils;
use MIME::Base64;
use utf8;
use Encode;

local $::SERVICE_NAME = "ad_admin_user_mu_ucn";
local $::PROTOCOL_VERSION = "3.0.0";
my $SCRIPT_VERSION = "3.0.1";

perunServicesInit::init;
my $DIRECTORY = perunServicesInit::getDirectory;
my $fileName = "$DIRECTORY/$::SERVICE_NAME".".ldif";

my $data = perunServicesInit::getHashedHierarchicalData;

#Constants
our $A_F_DOMAIN;  *A_F_DOMAIN = \'urn:perun:facility:attribute-def:def:adDomain';

our $A_LOGIN; *A_LOGIN = \'urn:perun:user:attribute-def:def:login-namespace:mu-adm';
our $A_FIRST_NAME;  *A_FIRST_NAME = \'urn:perun:user:attribute-def:core:firstName';
our $A_LAST_NAME;  *A_LAST_NAME = \'urn:perun:user:attribute-def:core:lastName';
our $A_DISPLAY_NAME;  *A_DISPLAY_NAME = \'urn:perun:user:attribute-def:core:displayName';
our $A_MAIL;  *A_MAIL = \'urn:perun:user:attribute-def:def:preferredMail';

our $A_MEMBER_STATUS; *A_MEMBER_STATUS = \'urn:perun:member:attribute-def:core:status';

our $STATUS_VALID; *STATUS_VALID = \'VALID';
our $STATUS_EXPIRED; *STATUS_EXPIRED = \'EXPIRED';

# Get the facility ID
my $facilityId = $data->getFacilityId();

# CHECK ON FACILITY ATTRIBUTES
if (!defined($data->getFacilityAttributeValue( attrName => $A_F_DOMAIN ))) {
	exit 1;
}

my $baseDN = "OU=PrivilegedUsers,OU=MU,DC=ucn,DC=muni,DC=cz";
my $domain = $data->getFacilityAttributeValue( attrName => $A_F_DOMAIN );
my $uac = "66048";

# GATHER USERS
my $users;  # $users->{$login}->{ATTR} = $attrValue;

#
# AGGREGATE DATA
#
# FOR EACH RESOURCE
foreach my $resourceId ( $data->getResourceIds() ){
        
	# EACH USER ON RESOURCE
	foreach my $memberId ($data->getMemberIdsForResource( resource => $resourceId )) {

		my $login = $data->getUserAttributeValue( member => $memberId, attrName => $A_LOGIN );
		next unless $login;
		my $memberStatus = $data->getMemberAttributeValue( member => $memberId, attrName => $A_MEMBER_STATUS );
		next unless ($memberStatus eq $STATUS_VALID);

		# store standard attrs
		$users->{$login}->{"DN"} = "CN=" . $login . "," . $baseDN;
		$users->{$login}->{$A_FIRST_NAME} = $data->getUserAttributeValue(member => $memberId, attrName => $A_FIRST_NAME);
		$users->{$login}->{$A_LAST_NAME} = $data->getUserAttributeValue(member => $memberId, attrName => $A_LAST_NAME);
		$users->{$login}->{$A_DISPLAY_NAME} = $data->getUserAttributeValue(member => $memberId, attrName => $A_DISPLAY_NAME);
		$users->{$login}->{$A_MAIL} = $data->getUserAttributeValue(member => $memberId, attrName => $A_MAIL);
	}
}

#
# PRINT user data LDIF
#
open FILE,">$fileName" or die "Cannot open $fileName: $! \n";
binmode FILE, ":utf8";

# FOR EACH USER ON FACILITY
my @logins = sort keys %{$users};
for my $login (@logins) {

	# print attributes, which are never empty
	print FILE "dn: " . $users->{$login}->{"DN"} . "\n";

	print FILE "cn: " . $login . "\n";
	print FILE "samAccountName: " . $login . "\n";
	print FILE "userPrincipalName: " . $login . "\@" . $domain . "\n";
	# enable accounts (if not) using service propagation
	print FILE "userAccountControl: " . $uac . "\n";

	# skip attributes which are empty and LDAP can't handle it (FIRST_NAME, EMAIL)
	my $sn = $users->{$login}->{$A_LAST_NAME};
	my $givenName = $users->{$login}->{$A_FIRST_NAME};
	my $displayName = ($users->{$login}->{$A_FIRST_NAME} || "") . " " . ($users->{$login}->{$A_LAST_NAME} || "") . " (adm)";
	my $mail = $users->{$login}->{$A_MAIL};

	if (defined $displayName and length $displayName) {
		print FILE "displayName: " . $displayName . "\n";
	}
	if (defined $sn and length $sn) {
		print FILE "sn: " . $sn . "\n";
	}
	if (defined $givenName and length $givenName) {
		print FILE "givenName: " . $givenName . "\n";
	}
	if (defined $mail and length $mail) {
		print FILE "mail: " . $mail . "\n";
	}

	# There MUST be an empty line after each entry, so entry sorting and diff works on slave part
	print FILE "\n";

}

close(FILE);

perunServicesInit::finalize;
