#!/usr/bin/perl

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

#Forward Declaration
sub processResourceData;
sub processMemberData;

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

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

#Constants
our $A_UF_LOGIN;                                *A_UF_LOGIN =                                \'urn:perun:user_facility:attribute-def:virt:login';
our $A_R_DESTINATION;                           *A_R_DESTINATION =                           \'urn:perun:resource:attribute-def:def:replicaDestination';
our $A_R_DESTINATION_PATH;                      *A_R_DESTINATION_PATH =                      \'urn:perun:resource:attribute-def:def:replicaDestinationPath';
our $A_R_SOURCE_PATH;                           *A_R_SOURCE_PATH =                           \'urn:perun:resource:attribute-def:def:replicaSourcePath';
our $A_R_IS_REPLICA_SOURCE_PATH_STANDALONE_DIR; *A_R_IS_REPLICA_SOURCE_PATH_STANDALONE_DIR = \'urn:perun:resource:attribute-def:def:isReplicaSourcePathStandaloneDir';

#Global data structure
our $struc = {};

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

foreach my $resourceId ( $data->getResourceIds() ) {
	processResourceData $resourceId;
}

foreach my $replicaDestinationPath (sort keys %$struc) {
	foreach my $replicaSourcePath (sort keys %{$struc->{$replicaDestinationPath}}) {
		foreach my $replicaDestination (sort keys %{$struc->{$replicaDestinationPath}->{$replicaSourcePath}}) {
			foreach my $login (sort keys %{$struc->{$replicaDestinationPath}->{$replicaSourcePath}->{$replicaDestination}}) {
				#use delimiter / if needed, or space if not needed
				my $delimiter;
				if($login eq "") { 
					$delimiter = " "; 
				} else {
					$delimiter = "/ ";
				}
				print FILE $replicaSourcePath, $login, $delimiter, $replicaDestination, ":", $replicaDestinationPath, "\n";
			}
		}
	}
}

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

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

# INPUT: replica's destination name, replica's destination path, replica's source path, member's id
# stores replica's destination name, replica's destination path, replica's source path 
# and user's login into $struc structure
sub processMemberData {
	my $replicaDestination = shift;
	my $replicaDestinationPath = shift;
	my $replicaSourcePath = shift;
	my $isReplicaStandAloneDir = shift;
	my $memberId = shift;

	my $login;
	#use empty login if this replica is standalone directory
	if($isReplicaStandAloneDir) {
		$login = "";
	} else {
		$login = $data->getUserFacilityAttributeValue( member => $memberId, attrName => $A_UF_LOGIN );
	}

	unless(exists $struc->{$replicaDestinationPath}->{$replicaSourcePath}->{$replicaDestination}->{$login}) {
		$struc->{$replicaDestinationPath}->{$replicaSourcePath}->{$replicaDestination}->{$login} = {};
	}
}

# INPUT: resource's id
# calls processMemberData to assign REPLICA_DESTINATION, REPLICA_DESTINATION_PATH 
# and REPLICA_SOURCE_PATH to the member of resource in $struc structure
sub processResourceData {
	my $resourceId = shift;

	my $replicaDestination = $data->getResourceAttributeValue( resource => $resourceId, attrName => $A_R_DESTINATION );
	my $replicaDestinationPath = $data->getResourceAttributeValue( resource => $resourceId, attrName => $A_R_DESTINATION_PATH );
	my $replicaSourcePath = $data->getResourceAttributeValue( resource => $resourceId, attrName => $A_R_SOURCE_PATH );
	my $isReplicaStandAloneDir = $data->getResourceAttributeValue( resource => $resourceId, attrName => $A_R_IS_REPLICA_SOURCE_PATH_STANDALONE_DIR );

	unless((substr $replicaDestinationPath, -1) eq "/") {
		$replicaDestinationPath = $replicaDestinationPath . "/";
	}

	unless((substr $replicaSourcePath, -1) eq "/") {
		$replicaSourcePath = $replicaSourcePath . "/";
	}

	foreach my $memberId( $data->getMemberIdsForResource( resource => $resourceId ) ) {
		processMemberData $replicaDestination, $replicaDestinationPath, $replicaSourcePath, $isReplicaStandAloneDir, $memberId;
	}
}

#####################################################

perunServicesInit::finalize;
