#!/usr/bin/perl

use strict;
use warnings;
use perunServicesInit;
use perunServicesUtils;
use Text::Unidecode;

our $SERVICE_NAME = "passwd_nfs4";
our $PROTOCOL_VERSION = "3.0.0";
my $SCRIPT_VERSION = "3.0.2";

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

#Constants
our $A_FACILITY_MIN_UID;                *A_FACILITY_MIN_UID =                      \'urn:perun:facility:attribute-def:virt:minUID';
our $A_FACILITY_MAX_UID;                *A_FACILITY_MAX_UID =                      \'urn:perun:facility:attribute-def:virt:maxUID';
our $A_USER_KERBEROS_LOGINS;            *A_USER_KERBEROS_LOGINS =                  \'urn:perun:user:attribute-def:def:kerberosLogins';
our $A_USER_FACILITY_UID;               *A_USER_FACILITY_UID =                     \'urn:perun:user_facility:attribute-def:virt:UID';
our $A_USER_FACILITY_GID;               *A_USER_FACILITY_GID =                     \'urn:perun:user_facility:attribute-def:virt:defaultUnixGID';
our $A_MEMBER_STATUS;                   *A_MEMBER_STATUS =                         \'urn:perun:member:attribute-def:core:status';

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

my $passwd_file_name = "$DIRECTORY/$::SERVICE_NAME";
my $min_uid_file_name = "$DIRECTORY/min_uid";
my $max_uid_file_name = "$DIRECTORY/max_uid";

###### min_uid and max_uid file #####
open MIN_UID,">$min_uid_file_name" or die "Cannot open $min_uid_file_name: $! \n";
open MAX_UID,">$max_uid_file_name" or die "Cannot open $max_uid_file_name: $! \n";
print MIN_UID $data->getFacilityAttributeValue(attrName => $A_FACILITY_MIN_UID), "\n";
print MAX_UID $data->getFacilityAttributeValue(attrName => $A_FACILITY_MAX_UID), "\n";
close MIN_UID;
close MAX_UID;
#####################################

####### passswd file ######################
my %lines;
my %nfsLines;

foreach my $resourceId ($data->getResourceIds()) {
	my %values;
	foreach my $memberId ($data->getMemberIdsForResource(resource => $resourceId)) {
		if($data->getMemberAttributeValue(attrName => $A_MEMBER_STATUS, member => $memberId) eq $STATUS_VALID) {
			my %logins = ();
			my %nfsLogins = ();
			# login can have 2 possible variant "login" and "nfs/login"
			# we don't want to have duplicits and for every login without 'nfs/' have a variant with 'nfs/'
			foreach my $kerberosLogin (@{$data->getUserAttributeValue(attrName => $A_USER_KERBEROS_LOGINS, member => $memberId)}) {
				if($kerberosLogin =~ /^nfs\//) {
					$nfsLogins{$kerberosLogin} = 1;
				} else {
					$logins{$kerberosLogin} = 1;
					my $nfsKerberosLogin = "nfs/" . $kerberosLogin;
					$nfsLogins{$nfsKerberosLogin} = 1;
				}
			}

			my $uid = $data->getUserFacilityAttributeValue(attrName => $A_USER_FACILITY_UID, member => $memberId);
			my $gid = $data->getUserFacilityAttributeValue(attrName => $A_USER_FACILITY_GID, member => $memberId);

			for my $login (keys %logins) {
				my $passwdLine = $login . ":x:" . $uid . ":" . $gid;
				$lines{$passwdLine} = 1;
			}
			for my $nfsLogin (keys %nfsLogins) {
				my $passwdLine = $nfsLogin . ":x:" . $uid . ":" . $gid;
				$nfsLines{$passwdLine} = 1;
			}
		}
	}
}
#print data to files
#case-insensitive sort of logins
open PASSWD,">$passwd_file_name" or die "Cannot open $passwd_file_name: $! \n";
for my $passwdLine (sort {"\U$a" cmp "\U$b"} keys %lines) {
	print PASSWD $passwdLine, "\n";
}
for my $nfsLine (sort {"\U$a" cmp "\U$b"} keys %nfsLines) {
	print PASSWD $nfsLine, "\n";
}
close(PASSWD);

#####################################################
perunServicesInit::finalize;
