#!/usr/bin/perl
use strict;
use warnings;
use perunServicesInit;
use perunServicesUtils;

local $::SERVICE_NAME = "vsup_web";
local $::PROTOCOL_VERSION = "3.0.0";
my $SCRIPT_VERSION = "3.0.8";

perunServicesInit::init;
my $DIRECTORY = perunServicesInit::getDirectory;
my $fileName = "$DIRECTORY/$::SERVICE_NAME".".csv";
my $fileNameCAO = "$DIRECTORY/$::SERVICE_NAME"."_cao.csv";
my $fileNameEXT = "$DIRECTORY/$::SERVICE_NAME"."_ext.csv";
my $fileNamePass = "$DIRECTORY/$::SERVICE_NAME"."_pass.csv";
my $fileNameNS = "$DIRECTORY/$::SERVICE_NAME"."_ns.csv";
my $data = perunServicesInit::getHashedDataWithGroups;

#Constants
our $A_LOGIN; *A_LOGIN = \'urn:perun:user_facility:attribute-def:virt:login';
our $A_UCO; *A_UCO= \'urn:perun:user:attribute-def:def:ucoVsup';
our $A_TITLE_BEFORE;  *A_TITLE_BEFORE = \'urn:perun:user:attribute-def:core:titleBefore';
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_TITLE_AFTER;  *A_TITLE_AFTER = \'urn:perun:user:attribute-def:core:titleAfter';
our $A_PHONE;  *A_PHONE = \'urn:perun:user:attribute-def:def:phoneDc2';
our $A_MOBILE;  *A_MOBILE = \'urn:perun:user:attribute-def:opt:mobilePhone';
our $A_EMAIL_PRIV;  *A_EMAIL_PRIV = \'urn:perun:user:attribute-def:opt:privateMail';
our $A_EMAIL_PRIV_KOS;  *A_EMAIL_PRIV_KOS = \'urn:perun:user:attribute-def:opt:privateMailKos';
our $A_PHONE_PRIV;  *A_PHONE_PRIV = \'urn:perun:user:attribute-def:opt:privatePhone';
our $A_FOTO;  *A_FOTO = \'urn:perun:user:attribute-def:def:cardPhoto';
our $A_EXCLUDED; *A_EXCLUDED = \'urn:perun:user:attribute-def:def:webExclude';

our $A_STUDY_ID;  *A_STUDY_ID = \'urn:perun:user:attribute-def:def:studyId';
our $A_STUDY_SINCE;  *A_STUDY_SINCE = \'urn:perun:user:attribute-def:def:studySince';
our $A_STUDY_PRIHLASKA;  *A_STUDY_PRIHLASKA = \'urn:perun:user:attribute-def:def:applicationId';
our $A_STUDY_ROCNIK;  *A_STUDY_ROCNIK = \'urn:perun:user:attribute-def:def:rocnik';
our $A_BIRTH_DATE;  *A_BIRTH_DATE = \'urn:perun:user:attribute-def:def:birthNumber';

our $A_VSUP_MAIL; *A_VSUP_MAIL= \'urn:perun:user:attribute-def:def:vsupMail';
our $A_VSUP_PREF_MAIL; *A_VSUP_PREF_MAIL= \'urn:perun:user:attribute-def:def:vsupPreferredMail';

our $A_ARTISTIC_FIRST_NAME; *A_ARTISTIC_FIRST_NAME = \'urn:perun:user:attribute-def:def:artisticFirstName';
our $A_ARTISTIC_LAST_NAME; *A_ARTISTIC_LAST_NAME = \'urn:perun:user:attribute-def:def:artisticLastName';

our $A_JOB;  *A_JOB = \'urn:perun:user:attribute-def:def:job';
our $A_JOB_ID;  *A_JOB_ID = \'urn:perun:user:attribute-def:def:jobId';
our $A_NS;  *A_NS = \'urn:perun:user:attribute-def:def:ns';

our $A_G_NAME;  *A_G_NAME = \'urn:perun:group:attribute-def:core:name';
our $A_G_CAO_ORGAN;  *A_G_CAO_ORGAN = \'urn:perun:group:attribute-def:def:caoOrgan';
our $A_G_CAO_FUNKCE;  *A_G_CAO_FUNKCE = \'urn:perun:group:attribute-def:def:caoFunkce';
our $A_G_CAO_FUNKCE_ID;  *A_G_CAO_FUNKCE_ID = \'urn:perun:group:attribute-def:def:caoFunkceId';

our $A_R_RELATION_TYPE; *A_R_RELATION_TYPE = \'urn:perun:resource:attribute-def:def:relationType';

# group attrs for NS
our $A_G_NS_NAME;  *A_G_NS_NAME = \'urn:perun:group:attribute-def:def:nsName';
our $A_G_NS_ID;  *A_G_NS_ID = \'urn:perun:group:attribute-def:def:nsId';

# GATHER USERS
my $users;  # $users->{$uco}->{ATTR} = $attrValue;
# Gather CAO membership
my $cao;    # $cao->{$organ}->{$funkce:$funkceId}->{$uco} = 1;
# Gather EXT membership
my $ext;   #  $ext->{$uco}->{ATTR} = $attrValue;
# Gather NS groups
my $groups;  # $groups->{ID}->{NAME/USERS} = name/{uco} = 1;

#
# AGGREGATE DATA
#
# FOR EACH USER
foreach my $resourceId ($data->getResourceIds()) {

	my $relationType = $data->getResourceAttributeValue(resource => $resourceId, attrName => $A_R_RELATION_TYPE);

	foreach my $groupId ($data->getGroupIdsForResource(resource => $resourceId)) {

		my $groupNamespaceId = $data->getGroupAttributeValue(group => $groupId, attrName => $A_G_NS_ID);
		my $groupNamespaceName = $data->getGroupAttributeValue(group => $groupId, attrName => $A_G_NS_NAME);
		my $groupCAOOrgan = $data->getGroupAttributeValue(group => $groupId, attrName => $A_G_CAO_ORGAN);
		my $groupCAOFunkce = $data->getGroupAttributeValue(group => $groupId, attrName => $A_G_CAO_FUNKCE);
		my $groupCAOFunkceId = $data->getGroupAttributeValue(group => $groupId, attrName => $A_G_CAO_FUNKCE_ID);

		if (defined $groupNamespaceId and defined $groupNamespaceName) {
			$groups->{$groupNamespaceId}->{"NAME"} = $groupNamespaceName;
		}

		foreach my $memberId ($data->getMemberIdsForResourceAndGroup( resource => $resourceId, group => $groupId )) {

			my $excluded = $data->getUserAttributeValue( member => $memberId, attrName => $A_EXCLUDED );

			if ($excluded) {
				# skip users, which shouldn't be displayed on the web
				next;
			}

			my $uco  = $data->getUserAttributeValue(member => $memberId, attrName => $A_UCO);
			my $login  = $data->getUserFacilityAttributeValue( member => $memberId, attrName => $A_LOGIN);
			my $prefMail = $data->getUserAttributeValue(member => $memberId, attrName => $A_VSUP_PREF_MAIL);
			my $vsupMail = $data->getUserAttributeValue(member => $memberId, attrName => $A_VSUP_MAIL);
			my $titleBefore = $data->getUserAttributeValue(member => $memberId, attrName => $A_TITLE_BEFORE);
			my $artisticFirstName = $data->getUserAttributeValue(member => $memberId, attrName => $A_ARTISTIC_FIRST_NAME);
			my $firstName = $data->getUserAttributeValue(member => $memberId, attrName => $A_FIRST_NAME);
			my $artisticLastName = $data->getUserAttributeValue(member => $memberId, attrName => $A_ARTISTIC_LAST_NAME);
			my $lastName = $data->getUserAttributeValue(member => $memberId, attrName => $A_LAST_NAME);
			my $titleAfter = $data->getUserAttributeValue(member => $memberId, attrName => $A_TITLE_AFTER);
			my $studyId = $data->getUserAttributeValue(member => $memberId, attrName => $A_STUDY_ID);
			my $studySince = $data->getUserAttributeValue(member => $memberId, attrName => $A_STUDY_SINCE);
			my $studyRocnik = $data->getUserAttributeValue(member => $memberId, attrName => $A_STUDY_ROCNIK);
			my $studyPrihlaska = $data->getUserAttributeValue(member => $memberId, attrName => $A_STUDY_PRIHLASKA);
			my $birthDate = $data->getUserAttributeValue(member => $memberId, attrName => $A_BIRTH_DATE);
			my $foto = $data->getUserAttributeValue(member => $memberId, attrName => $A_FOTO);
			my $phone = $data->getUserAttributeValue(member => $memberId, attrName => $A_PHONE);
			my $mobile = $data->getUserAttributeValue(member => $memberId, attrName => $A_MOBILE);
			my $emailPriv = $data->getUserAttributeValue(member => $memberId, attrName => $A_EMAIL_PRIV);
			my $emailPrivKOS = $data->getUserAttributeValue(member => $memberId, attrName => $A_EMAIL_PRIV_KOS);
			my $phonePriv = $data->getUserAttributeValue(member => $memberId, attrName => $A_PHONE_PRIV);
			my $job = $data->getUserAttributeValue(member => $memberId, attrName => $A_JOB);
			my $jobId = $data->getUserAttributeValue(member => $memberId, attrName => $A_JOB_ID);
			my $ns = $data->getUserAttributeValue(member => $memberId, attrName => $A_NS);
			my $userId = $data->getUserIdForMember(member => $memberId);

			$users->{$uco}->{$A_LOGIN} = $login;
			$users->{$uco}->{'EMAIL'} = ($prefMail || ($vsupMail || $login . '@vsup.cz'));

			# personal
			$users->{$uco}->{$A_TITLE_BEFORE} = $titleBefore || '';
			$users->{$uco}->{$A_FIRST_NAME} = ($artisticFirstName || ($firstName || ''));
			$users->{$uco}->{$A_LAST_NAME} = ($artisticLastName || ($lastName || ''));
			$users->{$uco}->{$A_TITLE_AFTER} = $titleAfter || '';

			$users->{$uco}->{$A_STUDY_ID} = $studyId || '';
			$users->{$uco}->{$A_STUDY_SINCE} = $studySince || '';
			$users->{$uco}->{$A_STUDY_ROCNIK} = $studyRocnik || '';
			$users->{$uco}->{$A_STUDY_PRIHLASKA} = $studyPrihlaska || '';

			# Convert BirthNumber to birth date
			if (defined $birthDate) {

				my $YY = substr($birthDate, 0, 2);
				my $MM = substr($birthDate, 2, 2);
				my $DD = substr($birthDate, 4, 2);

				# fix womans birth number month
				if (substr($MM, 0, 1) eq "5") {
					$MM = "0" . substr($birthDate, 3, 1);
				}
				if (substr($MM, 0, 1) eq "6") {
					$MM = "1" . substr($birthDate, 3, 1);
				}

				$users->{$uco}->{$A_BIRTH_DATE} = $DD . $MM . $YY;

			} else {
				$users->{$uco}->{$A_BIRTH_DATE} = '';
			}

			$users->{$uco}->{$A_FOTO} = $foto || '';

			# work contacts
			$users->{$uco}->{$A_PHONE} = $phone || '';
			$users->{$uco}->{$A_MOBILE} = $mobile || '';
			$users->{$uco}->{$A_EMAIL_PRIV} = $emailPriv || ($emailPrivKOS || '');
			$users->{$uco}->{$A_PHONE_PRIV} = $phonePriv || '';

			# cao membership
			if (defined $groupCAOOrgan and length $groupCAOOrgan) {
				$cao->{$groupCAOOrgan}->{$groupCAOFunkce.":".$groupCAOFunkceId}->{$uco} = 1;
			}

			# external workers
			if (defined $relationType) {
				$ext->{$uco}->{"TYPE"} = $relationType;
				$ext->{$uco}->{$A_JOB} = $job || '';
				$ext->{$uco}->{$A_JOB_ID} = $jobId || '';
				$ext->{$uco}->{$A_NS} = $ns || '';
				$ext->{$uco}->{"USER_ID"} = $userId;
			}

			# is from NS group
			if (defined $groupNamespaceId and defined $groupNamespaceName) {

				# fill person to NS
				$groups->{$groupNamespaceId}->{"USERS"}->{$uco} = 1;

			}

		}
	}
}

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

# print personal info
my @keys = sort keys %{$users};
for my $uco (@keys) {

	# print attributes, which are never empty
	print FILE $uco . "\t" . $users->{$uco}->{$A_LOGIN} . "\t" . $users->{$uco}->{'EMAIL'} . "\t" .
		$users->{$uco}->{$A_TITLE_BEFORE} . "\t" . $users->{$uco}->{$A_FIRST_NAME} . "\t" .
		$users->{$uco}->{$A_LAST_NAME} . "\t" . $users->{$uco}->{$A_TITLE_AFTER} . "\t" .
		$users->{$uco}->{$A_PHONE} . "\t" . $users->{$uco}->{$A_MOBILE} . "\t" .
		$users->{$uco}->{$A_EMAIL_PRIV} . "\t" . $users->{$uco}->{$A_PHONE_PRIV} . "\t" .
		$users->{$uco}->{$A_FOTO} . "\n";

}

close(FILE);

open FILE,">$fileNamePass" or die "Cannot open $fileNamePass: $! \n";
binmode FILE, ":utf8";

# first password app
my @passKeys = sort keys %{$users};
for my $uco (@passKeys) {

	if ($users->{$uco}->{$A_STUDY_ID} and $users->{$uco}->{$A_STUDY_PRIHLASKA} and length $users->{$uco}->{$A_BIRTH_DATE}) {
		# print only users with at least one study (now or in history)
		print FILE $uco . "\t" . $users->{$uco}->{$A_STUDY_ID} . "\t" . $users->{$uco}->{$A_STUDY_SINCE} . "\t" .
			$users->{$uco}->{$A_STUDY_PRIHLASKA} . "\t" . $users->{$uco}->{$A_STUDY_ROCNIK} . "\t" .
			$users->{$uco}->{$A_BIRTH_DATE} . "\n";
	}

}

close(FILE);

open FILE,">$fileNameCAO" or die "Cannot open $fileNameCAO: $! \n";
binmode FILE, ":utf8";

# print CAO
my @cao_keys = sort keys %{$cao};
for my $ao (@cao_keys) {

	my @funkce = sort keys %{$cao->{$ao}};
	for my $fce (@funkce) {

		my ($fce_name, $fce_id) = split(":", $fce);

		for my $uco (sort keys %{$cao->{$ao}->{$fce}}) {

			# print attributes, which are never empty
			print FILE $uco."\t".$ao."\t".$fce_name."\t".$fce_id."\n";

		}

	}

}

close(FILE);

open FILE,">$fileNameEXT" or die "Cannot open $fileNameEXT: $! \n";
binmode FILE, ":utf8";

# print EXT
my @ext_keys = sort keys %{$ext};
for my $uco (@ext_keys) {

	# print attributes, which are never empty
	print FILE $uco . "\t" . $ext->{$uco}->{"USER_ID"} . "\t" . $ext->{$uco}->{"TYPE"} . "\t" .
		$ext->{$uco}->{$A_JOB} . "\t" . $ext->{$uco}->{$A_JOB_ID} . "\t" . $ext->{$uco}->{$A_NS}  . "\n";

}

close(FILE);

open FILE,">$fileNameNS" or die "Cannot open $fileNameNS: $! \n";
binmode FILE, ":utf8";

# FOR EACH NS GROUP
my @ns_keys = sort keys %{$groups};
for my $key (@ns_keys) {
	my $name = $groups->{$key}->{"NAME"};
	my @ucos = sort keys %{$groups->{$key}->{"USERS"}};
	for my $uco (@ucos) {
		print FILE $key . "\t" . $name . "\t" . $uco . "\n";
	}
}

close(FILE);

perunServicesInit::finalize;
