#!/usr/bin/perl -w

#
# glite-info-glue2-service: an information provider for the Service
# object, in v 2.0 of the GLUE schema
#
# Ref: http://www.ogf.org/documents/GFD.147.pdf
#      http://glue20.web.cern.ch/glue20/
#
# In general this provider is expected to be called from a wrapper
# which also generates Endpoint objects, but it can be used standalone
# for simple cases.
#
# Stephen Burke, v 1.0 February 2010
#
# 05/04/11: Remove objectClass: GLUE2Entity line as it doesn't seem to be needed
#
# Arguments are:
#    -   the GLUE2DomainID (i.e. the site unique ID)
#    -   the GLUE2ServiceID (i.e. the unique ID for the Service object),
#        optionally followed by a comma-separated list of associated Services
#    -   the ServiceType, optionally with a comma-separated list of
#        Capabilities appended
#    -   Endpoint summary information, consisting of the highest QualityLevel,
#        the complexity (default 1:0:0), and an optional list of
#        StatusInfo URLs, all comma-separated
#    -   an optional list of strings to be printed as OtherInfo attributes
#
# Copyright (c) Members of the EGEE Collaboration. 2010.
# See http://www.eu-egee.org/partners/ for details on the copyright
# holders.
#
#     Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

use strict;
use POSIX qw(strftime);

# Version number for this code
my $gigs_version = "1.1";

# Hostname for debugging info
my $host = `hostname -f`;
chomp($host);

# This is where we put the object in the DIT
my $bind_dn = "GLUE2GroupID=resource,o=glue";

# Hardwire the data validity period to 1 hour for now
my $validity = "3600";

# Process the arguments - must be at least 4

if (!($ARGV[3])){
    print STDERR "Usage: glite-info-glue2-service <site-ID> <service-ID> <service-type> <endpoint-info> [<other-info> [<other-info>] ...]\n";
    exit 1;
}

my $SiteID = shift @ARGV;

# No white space
$SiteID =~ s/\s+//g;

my $ServiceIDs = shift @ARGV;

# No white space
$ServiceIDs =~ s/\s+//g;

# Allow for extra ServiceIDs to represent Service-Service relations

my @RelatedServices = split /,/, $ServiceIDs;

# The first one is us

my $UID = shift @RelatedServices;

my $TypeCap = shift @ARGV;

# No white space
$TypeCap =~ s/\s+//g;

# Any Capabilities are appended to the Type, comma-separated
# NB Assumes that commas are not allowed in these attributes

my @Capabilities = split /,/, $TypeCap;
my $Type = shift @Capabilities;

my $EndpointInfo = shift @ARGV;

# No white space
$EndpointInfo =~ s/\s+//g;

# EndpointInfo contains the QualityLevel, complexity and
# optional StatusInfo endpoints, comma-separated
# NB Assumes that commas are not allowed in these attributes

my @Info = split /,/, $EndpointInfo;
my $QualityLevel = shift @Info;
my $Complexity = shift @Info;

if (!$Complexity) {
    $Complexity = 1;
}

# Split the Complexity into its three components
(my $EndpointCount, my $ShareCount, my $ResourceCount) = split /:/, $Complexity, 3;

if (!$EndpointCount) {
    $EndpointCount = 0;
}

if (!$ShareCount) {
    $ShareCount = 0;
}

if (!$ResourceCount) {
    $ResourceCount = 0;
}

# Check that we still have non-null values where necessary

if (!$SiteID || !$UID || !$Type || !$QualityLevel) {
    print STDERR "Usage: glite-info-glue2-service <site-ID> <service-ID> <service-type> <endpoint-info> [<other-info> [<other-info>] ...]\n";
    exit 2;
}

# Sweep up anything left

my @OtherInfo = @ARGV;

# Now start outputting LDIF lines for the Service object.
# Note that once we get here we are committed to printing a
# complete, valid object. Start with the DN ...

print "dn: GLUE2ServiceID=$UID,$bind_dn\n";

# Print the boilerplate objectclass declarations and unique ID

print "objectClass: GLUE2Service\n";

# This is a bit of a kludge to provide some quick support for
# ComputingService and StorageService. The real things will need
# a lot more work.

if ($Type eq "org.glite.ce") {
    print "objectClass: GLUE2ComputingService\n";
} elsif ($Type eq "org.glite.se") {
    print "objectClass: GLUE2StorageService\n";
}

print "GLUE2ServiceID: $UID\n";

# Attributes are generally dealt with in the order in which they appear
# in the GLUE 2 specification document, unless dependencies dictate
# otherwise.

# Creation time and validity are standard attributes for all objects

# Times are mandated to be UTC only
my $TimeNow = strftime("%Y-%m-%dT%H:%M:%SZ", gmtime());
print "GLUE2EntityCreationTime: $TimeNow\n";

# Validity is currently hardwired above
print "GLUE2EntityValidity: $validity\n";

# The name is just an indicative human-readable string, here of the
# form site-type (taking the last component of compound types).

my @last = split /\./, $Type;
my $Name = $SiteID . "-" . $last[$#last];

print "GLUE2EntityName: $Name\n";

# Use OtherInfo to embed some metadata to help with debugging

print "GLUE2EntityOtherInfo: InfoProviderName=glite-info-glue2-service\n";
print "GLUE2EntityOtherInfo: InfoProviderVersion=$gigs_version\n";
print "GLUE2EntityOtherInfo: InfoProviderHost=$host\n";

# Print any more OtherInfo

foreach (@OtherInfo) {
# Basically just print this as it comes, but no leading or trailing white
# space and no blank lines
    s/^\s+//;
    s/\s+$//;
    if ($_) {
	print "GLUE2EntityOtherInfo: $_\n";
    }
}

foreach (@Capabilities) {
# Should be no need for validation as it will be fixed per service type,
# but make sure we don't emit a blank string as it isn't valid LDIF
    if ($_) {
        print "GLUE2ServiceCapability: $_\n";
    }
}

print "GLUE2ServiceType: $Type\n";

print "GLUE2ServiceQualityLevel: $QualityLevel\n";

foreach (@Info) {
# This is supposed to be a URL but we'll print it as it comes,
# but make sure we don't emit a blank string as it isn't valid LDIF
    if ($_) {
	print "GLUE2ServiceStatusInfo: $_\n";
    }
}

# These should be integers, but just print whatever we got

print "GLUE2ServiceComplexity: endpointType=$EndpointCount, share=$ShareCount, resource=$ResourceCount\n";

# Upward reference to the hosting site (AdminDomain)

print "GLUE2ServiceAdminDomainForeignKey: $SiteID\n";

# Allow for possible Service-Service relations
# Other relations will point to the Service and not from it

foreach (@RelatedServices) {
# Make sure we don't emit a blank string as it isn't valid LDIF
    if ($_) {
        print "GLUE2ServiceServiceForeignKey: $_\n";
    }
}

# print a newline to finish the object
print "\n";

exit 0;
