#!/usr/bin/perl
#
# scan job execution log file from the LCG grid, and use convert2swf_v2.pm
# to convert the data into the standard workload format.
#

use warnings;
use strict;
use Time::Local;
use POSIX;
use convert2swf_v2;


############################
#
# DO THE CONVERSION:
#

my $tz_str    = "Europe/London";
my $max_procs = 24515;
my @queues    = ();

$ENV{TZ} = $tz_str;
POSIX::tzset();

SWF::init( $tz_str, $max_procs, \@queues );

my $format_bugs;
my $jobs_data = get_jobs();

my ($zero, $maxtime) = SWF::convert( $jobs_data, $format_bugs, 1 );

my $header = generate_header( $zero, $maxtime, $max_procs );

SWF::print( $header );



############################
# SPECIFICS for Sharcnet workload

# the format of each entry includes the following space-separated fields:
#  0 unix timestamp (presumably submit time)
#  1 group name
#  2 user ID
#  3 CE name
#  4 run time


my $job_cnt;

sub get_jobs {
##############
# parse input format and create a hash for each job

    my @list_of_jobs;

    #
    # scan trace and collect job info
    #
    while (<>) {


#if ($job_cnt == 10000) {last;}

	#
	# parse line and extract info
	#

	if (/^\s*$/) {		# empty line
	    next;
	}

	$_ =~ /\s*(.*)\s*/;		# get rid of white space at ends
	$_ = $1;
	my @line = split(' ');	# split into fields

	if ($#line != 4) {
	    $format_bugs .= "format_problem $_\n";
	    warn(">>>Format problem on $_\ngot $#line fields (should be 4)");
	    next;
	}

	my %nj;

	#
	# set the desired fields as specified in convert2swf.pl
	#

	$nj{trace}  = $_;	# used for error messages

	my $submit;
	if ($line[0] =~ /(-?\d+(\.\d+)?)/) {
	    $submit = $1;
	    $nj{submit}  = $submit;
	}

	my $run;
	if ($line[4] =~ /(-?\d+(\.\d+)?)/) {
	    $run = $1;
	    $nj{run} = $run;
	}

	$nj{procs} = 1;

	my $user;
	if ($line[2] =~ /(\w+)/) {
	    $user = $1;
	    $nj{user} = $user;
	}

	my $group;
	if ($line[1] =~ /(\w+)/) {
	    $group = $1;
	    $nj{group} = $group;
	}

	# try to catch last 3 components of IP address
	my $partition;
	if ($line[3] =~ /([\w_-]+\.[\w_-]+\.[\w_-]+)$/) {
	    $partition = $1;
	    $nj{partition} = $partition;
	}

	$list_of_jobs[$job_cnt++] = \%nj;
    }

    return \@list_of_jobs;
}


sub generate_header {
    my ($zero, $maxtime, $max_procs) = @_;

    my ($sec, $min, $hr, $mday, $mon, $year, $wday, $yday, $isdst);

    $header  = "; Version: 2.2\n";
    $header .= "; Computer: various\n";
    $header .= "; Installation: LCG grid\n";

    $header .= "; Acknowledge: Hui Li\n";
    $header .= "; Information: http://lcg.web.cern.ch/LCG/\n";
    $header .= ";              http://www.cs.huji.ac.il/labs/parallel/workload/\n";

    $header .= sprintf("; Conversion: Dror Feitelson (feit\@cs.huji.ac.il) %s\n",
		       strftime("%d %b %Y", localtime()));


    $header .= sprintf("; MaxJobs: %d\n", $job_cnt);
    $header .= sprintf("; MaxRecords: %d\n", $job_cnt);
    $header .= "; Preemption: Yes\n";

    $header .= sprintf("; UnixStartTime: %d\n", $zero);
    $header .= "; TimeZone: 0\n";
    $header .= sprintf("; TimeZoneString: %s\n", $tz_str);

    $header .= sprintf("; StartTime: %s\n",
	   strftime("%a %b %2d %H:%M:%S %Z %Y", localtime($zero)));

    $header .= sprintf("; EndTime:   %s\n",
	   strftime("%a %b %2d %H:%M:%S %Z %Y", localtime($maxtime)));

    $header .= "; MaxProcs: $max_procs\n";

    return $header;
}

