#!/usr/local/bin/perl -w

$DEBUG = 1;

if ($DEBUG){
        open LOG, ">"."js1.log" or die "Cannot open js1.log"; 
}


%name = (
    "PRESS" => 1,
    "SAW"  =>  3,
    "LATHE" => 2,
    "MILL"  => 1,
    "SHAPER" => 1,
    "GRINDER" => 1,
    "WELDER" => 1,
    "DRILL" => 2,
);
$N=8;
%busy = %name;
@an = ([0, 8, 0], [1, 0, 0]);
open IN , "<".$ARGV[0] or die "Cannot open $ARGV[0]:$!";
while (<IN>){
    chomp;
    $count++;
    ($d[$count], $h[$count], $m[$count])= split /\s+/, $_;
    $total[$count]=$d[$count]*24+$h[$count]+$m[$count]/60;
    chomp ($s = <IN>);
    @s = split /\s+/, $s;
    $c=0;
    while (@s){
	$c++;
	$seq[$count][$c]=shift @s;
	$seq[$count][++$c]=shift @s;
	$total[$count] += $seq[$count][$c];
    }
    print "Minimun time for completion job $count is $total[$count]\n";
}
close IN;
$jobs=0;
$time=0;
$ok=0;
$timeunit=1/(60*60);
for $day (0..30){
    for $hour (0..23){
	for $minu (0..59){
            for $seco (0..59){
            for (1..$count){
                if (defined $job[$_]) {
                    if ($job[$_]==0) {
                       event($_);
                    }
                }elsif ($day==$d[$_] && $hour==$h[$_] && $minu==$m[$_] && $seco==0){
                    event($_);
                }
	    }
	    if ($jobs==$count && $ok==0) { $totaltime=$time; $ok=1; }
	    for (0..$#an){
                if ($day==$an[$_][0] && $hour==$an[$_][1] && $minu==$an[$_][2] && $seco==0){
		    report($_);
		}
	    }
            $time += $timeunit;
            }
	}
    }
}
if ($DEBUG){ close LOG; }



sub event{
    my $i = shift;
    if (!defined $startevent[$i]){ # start a job
	$j[$i] = 1;
	$job[$i]=0;
        $machine[$i]=$seq[$i][1];
        $startevent[$i]=$time;
        if ($DEBUG){
                print LOG "$time: Job $i started\n";
        }
    }
    if (!defined $stopevent[$i][$j[$i]]){  # waiting for a machine
        if ($busy{$machine[$i]}<=0){
	    cola($i);
        }elsif ( @{ $machine[$i] } ){
	    $z = shift @{$machine[$i]};
	    procesa($z);
	}else{
	    procesa($i);
	}
    }
    if (defined $stopevent[$i][$j[$i]]){ # start a new subprocess
	if ($time >= $stopevent[$i][$j[$i]]){

            if ($DEBUG){
                print LOG "$time: Job $i stopped being processed in $machine[$i]\n";
            }

            $busy{$machine[$i]}++;
	    if ($busy{$machine[$i]}>$name{$machine[$i]}){
		$busy{$machine[$i]}=$name{$machine[$i]};
	    }
            $j[$i]+=2;
	    $machine[$i]=$seq[$i][$j[$i]];
            if (!defined $machine[$i] && $job[$i]==0){
		$timejob[$i]=$time-$startevent[$i];
		$job[$i]=1;
		$jobs++;
                if ($DEBUG) {
                        print LOG "$time: Job $i finished\n";
                }
		return ;
	    }
	}else{ # processing
	}
    }
}

sub cola{
    my $i = shift;
    $busy{$machine[$i]}=0;
    $queue{$machine[$i]}+=$timeunit;
    $totalqueue+=$timeunit;
    unless (grep $i, @{ $machine[$i] } ){
	push @{ $machine[$i] }, $i;
	$len{$machine[$i]}++;
        if ($DEBUG){
                print LOG "$time: Job $i enters in queue $machine[$i]\n";
                print LOG "       The queue is now: @{ $machine[$i] }\n";
        }
    }
}

sub procesa{
    my $i = shift;
    $busy{$machine[$i]}--;
    $stopevent[$i][$j[$i]]=$time+$seq[$i][$j[$i]+1];
    if ($DEBUG){
        if (!defined $queue{$machine[$i]}) { $queue{$machine[$i]}=0; }
        print LOG "$time: Job $i after $queue{$machine[$i]} queue, is being processed by $machine[$i]\n";
    }
}

sub report{
    print "Elapsed time is $time\n";
    print "Number of jobs completed is $jobs\n";
    if (defined $totaltime){
	print "All jobs completed in $totaltime\n";
    }
    $mean=0;
    for (1..$count){
        if ($job[$_]==1){
            $mean += $timejob[$_];
        }
    }
    if ($jobs>0){
       $mean /= $jobs;
       print "Average time for completion is $mean\n";
    }
    print "QUEUE TIME STATUS:\n";
    for my $i (keys %name){
	if (!defined $queue{$i}) { $queue{$i}=0; }
        print "average queue $i ", $queue{$i}/$name{$i}, "\n";
    }
    print "Total queue time is ",$totalqueue,"\n";
    print "MEAN QUEUE LENGTH:\n";
    $cc=0;
    $overall=0;    
    for my $i (keys %name){
        if (!defined $len{$i}){ $len{$i}=0; }
        $cc++;
        print "length queue $i ", $len{$i}/$N , "\n";
        $overall+= $len{$i}/$N;
    }
    print "Overall queue length ", $overall/$N, "\n";
    print "JOB STATUS:\n";
    for (1 .. $count){
	if (!defined $job[$_]){
	    print "Job $_ not started\n";
	}elsif ($job[$_]==1){
	    print "Job $_ completed in $timejob[$_]\n";
	}elsif ($job[$_]==0){
	    print "Job $_ started, not completed\n";
	}else{
	    print "Error in job $_\n";
	}
    }
    print "\n";
}

__END__
