#!/usr/bin/perl

use strict;
use warnings;
use Getopt::Long qw(:config no_ignore_case);
use Perun::Agent;
use Perun::Common qw(printMessage);

sub help {
	return qq{
	Creates a new facility like recently created facility.
	------------------------------------------------------
	Available options:
	--likeFacility   | -l name of 'like' facility
	--facilityName   | -F facility name
	--facilityDsc    | -D facility description
	--nodeName       | -n name of node
	--fromNumber     | -o numbering of nodes starts from
	--toNumber       | -d numbering of nodes ends to
	--specialNodes   | -p list of special node names
	--skipFacCreation | -s skip creation of facility
	--batch          | -b batch
	--help           | -h prints this help

	};
}

my ($facilityName, $facilityDescription, $batch, $likeFacility, $nodeName, $fromNumber, $toNumber, $skipFac, @specnodes);
my %usedServices;

GetOptions ("help|h"   => sub {
		print help();
		exit 0;
	}, "batch|b"       => \$batch,
	"likeFacility|l=s" => \$likeFacility,
	"facilityDsc|D=s" => \$facilityDescription,
	"nodeName|n=s"     => \$nodeName,
	"fromNumber|o=i"   => \$fromNumber,
	"toNumber|d=i" => \$toNumber,
	'specialNodes|p=s@{0,}' => \@specnodes,
	"skipFacCreation|s" => \$skipFac,
	"facilityName|F=s" => \$facilityName) || die help();

# Check options
unless (defined($facilityName)) { die "ERROR: facilityName is required \n";}
unless (defined($likeFacility)) { die "ERROR: likeFacility is required \n";}

unless (defined($nodeName)) {$nodeName = $facilityName;}

my ($facility,$facilityId,@hosts);
my $agent = Perun::Agent->new();
my $facilitiesAgent = $agent->getFacilitiesAgent;
my $attributesAgent = $agent->getAttributesAgent;

# zjisteni id likeFacility
my $facilityO = $facilitiesAgent->getFacilityByName( name => $likeFacility );
my $facilityIdO = $facilityO->getId;

# vytvoreni facility
unless ($skipFac) {
	my $facility = Perun::beans::Facility->new;
	$facility->setName( $facilityName );
	if (defined($facilityDescription)) {
		$facility->setDescription( $facilityDescription );
	}

	$facility = $facilitiesAgent->createFacility( facility => $facility );
	$facilityId = $facility->getId;

	printMessage("Facility Id:".$facilityId." successfully created", $batch);

	unless (defined($fromNumber) or defined($toNumber)) {
		# zjisteni poctu hostu likeFacility
		my @hostsO = $facilitiesAgent->getHosts( facility => $facilityIdO );
		unless (@hostsO) {
			printMessage "No host found", $batch;
			exit 0;
		}
		$fromNumber = 1;
		$toNumber = @hostsO;
	}

	# vytvoreni nodes
	my ($hlava, $ocasek) = split (/\./, $facilityName, 2);

	my $ii;
	my $jj = 0;
	for ($ii = $fromNumber; $ii <= $toNumber; $ii++) {
		$hosts[$jj] = $hlava.$ii.".".$ocasek;
		$jj++;
	}

	$facilitiesAgent->addHosts( facility => $facilityId, hostnames => \@hosts );

	printMessage("Hosts '@hosts' successfully added on the facility Id:$facilityId", $batch);

	# pridani special nodes
	if (@specnodes>0) {
		$facilitiesAgent->addHosts( facility => $facilityId, hostnames => \@specnodes );
		printMessage("Hosts '@specnodes' successfully added on the facility Id:$facilityId", $batch);
		push (@hosts,@specnodes);
	}

	# nastaveni facility atributu
	$facilitiesAgent->copyAttributes(srcFacility => $facilityIdO, destFacility => $facilityId);

	# nastaveni owners
	$facilitiesAgent->copyOwners(srcFacility => $facilityIdO, destFacility => $facilityId);

	# nastaveni managers
	$facilitiesAgent->copyManagers(srcFacility => $facilityIdO, destFacility => $facilityId);

} else {
	# zjisteni id nove Facility
	$facility = $facilitiesAgent->getFacilityByName( name => $facilityName );
	$facilityId = $facility->getId;
}

# zjisteni resources
my $resourcesAgent = $agent->getResourcesAgent;
my $vosAgent = $agent->getVosAgent;
my @resourcesO = $facilitiesAgent->getAssignedResources( facility => $facilityIdO );
unless (@resourcesO) {
	printMessage "No Resources assigned", $batch;
	exit 0;
}

foreach my $resourceO (@resourcesO) {
	eval {
	my $resourceIdO = $resourceO->getId;
	my $resourceNameO = $resourceO->getName;
	my $voId = $resourceO->getVoId( resource => $resourceIdO );
	my $vo = $vosAgent->getVoById( id => $voId );
	# vytvoreni resources
	my $resource = Perun::beans::Resource->new;
	my $resourceName = $resourceNameO;
	$resourceName =~ s/$likeFacility/$facilityName/;
	$resource->setName( $resourceName );
	my $resourceDescription=$resourceO->getDescription;
	$resourceDescription =~ s/$likeFacility/$facilityName/;
	$resource->setDescription( $resourceDescription);
#	$resource->setVoId($voId);
#	$resource->setFacilityId($facilityId);
	$resource = $resourcesAgent->createResource( resource => $resource, vo => $voId, facility => $facilityId );
	printMessage("Resource Id:".$resource->getId." successfully created", $batch);
	# nastaveni resource atributu
	my @attributesrO = $attributesAgent->getAttributes( resource => $resourceIdO );
	for (my $kk = 0; $kk < 3; $kk++) {
		foreach my $attributer (@attributesrO) {
			my @pom = split(/\:/, $attributer->getName);
			if ($pom[4] ne "core" and $pom[4] ne "virt") {
				eval {
					$attributesAgent->setAttribute( resource => $resource->getId, attribute => $attributer );
				};
			}
		}
	}

	# zjisteni services
	my @servicesO = $resourcesAgent->getAssignedServices( resource => $resourceIdO );
	if (@servicesO) {
		foreach my $serviceO (@servicesO) {
			# prirazeni services
			$resourcesAgent->assignService( resource => $resource->getId, service => $serviceO->getId );
			printMessage("Service Id:".$serviceO->getId." successfully assigned to the resource Id:".$resource->getId, $batch);
			$usedServices{$serviceO->getId} = 1;
		}
	} else {
		printMessage "No Service found", $batch;
	}

	# zjisteni groups
	my @groupsO = $resourcesAgent->getAssignedGroups( resource => $resourceIdO );
	if (@groupsO) {
		foreach my $groupO (@groupsO) {
			# prirazeni groups
			$resourcesAgent->assignGroupToResource( resource => $resource->getId, group => $groupO->getId );
			if ($@) { warn "Error in assign group:".$@."\n"; }
			printMessage("Group Id:".$groupO->getId." successfully assigned to the resource Id:".$resource->getId, $batch);
		}
	} else {
		printMessage "No Group found", $batch;
	}
	};
	#my $withGroups=1;
	#$resourcesAgent->copyResource(templateResource => $resourceO, destinationResource => $resource, withGroups => $withGroups );
}

# prirazeni destinations
# lepe nastavit pres GUI, neb se neda obecne urcit, ktere destinations maji mit ktere sluzby

printMessage
	"PLEASE CHECK VALUES OF ATTRIBUTES NAMELY ATTRIBUTES FOR SERVICE pbsmon_json. UPDATE DESCRIPTIONS ON RESOURCES!!! SET DESTINATIONS BY GUI !!!",
	$batch;
