#!/usr/lobal/bin/perl
=pod

=head1
	perl log2phasecvs.pl [-cCdwWvtTusSr param] -b binpath  logfilepath

=options

	cwtsは必須．パラメータの固定値もしくは最小値．
	最大値と幅が指定されていない場合は固定値扱い．
	最大値と幅が指定されていた場合は最小値扱い．

	CWTSは最大値．この値を超えないようにパラメータを割り振る．
	dvurは幅．最小値＋幅×Ｎ の値が最大値を超えない最大のＮまでパラメータを割り付ける．

=head4 b binpath
	スクリプト群の置いてあるパス

=head4 c
=head4 C
=head4 d

=head4 w
=head4 W
=head4 v

=head4 t
=head4 T
=head4 u

=head4 s
=head4 S
=head4 r

=cut

use strict;
use warnings;
use Getopt::Std;
#use Tie::File;

use lib qw(/home/kir/wtnb-y/LAB/Separator/bin); #------------------------------------------------------------------------------------------------------ hardcoding!

use File::Copy;
use File::ReadBackwards;


#use Time::HiRes qw( usleep ualarm gettimeofday tv_interval );




my %opt;
getopts('b:c:C:d:w:W:v:t:T:u:s:S:r:',\%opt);

my($cmin, $cmax, $cinterval);
if( $opt{'c'} and $opt{'c'} =~ /^\d+$/ and $opt{'w'} > 0){ $cmin = $opt{'c'}; } else { $cmin = 1; }
if( $opt{'C'} and $opt{'C'} =~ /^\d+$/ ){ $cmax = $opt{'C'}; } else { $cmax = $cmin; }
if( $opt{'d'} and $opt{'d'} =~ /^\d+$/ and $opt{'d'} > 0 ){ $cinterval = $opt{'d'}; } else { $cinterval = 1; }

my($wmin, $wmax, $winterval);
if( $opt{'w'} and $opt{'w'} =~ /^\d+$/ and $opt{'w'} > 0){ $wmin = $opt{'w'}; } else { $wmin = 1; }
if( $opt{'W'} and $opt{'W'} =~ /^\d+$/ ){ $wmax = $opt{'W'}; } else { $wmax = $wmin; }
if( $opt{'v'} and $opt{'v'} =~ /^\d+$/ and $opt{'v'} > 0 ){ $winterval = $opt{'v'}; } else { $winterval = 1; }

my($tmin, $tmax, $tinterval);
if( $opt{'t'} and $opt{'t'} =~ /^[01][\.\d+]*$/ and $opt{'t'} > 0){ $tmin = $opt{'t'}; } else { $tmin = 0; }
if( $opt{'T'} and $opt{'T'} =~ /^[01][\.\d+]*$/ ){ $tmax = $opt{'T'}; } else { $tmax = $tmin; }
if( $opt{'u'} and $opt{'u'} =~ /^[01][\.\d+]*$/ and $opt{'u'} > 0 ){ $tinterval = $opt{'u'}; } else { $tinterval = 1; }

my($smin, $smax, $sinterval);
if( $opt{'s'} and $opt{'s'} =~ /^\d+$/ and $opt{'s'} > 0){ $smin = $opt{'s'}; } else { $smin = 1; }
if( $opt{'S'} and $opt{'S'} =~ /^\d+$/ ){ $smax = $opt{'S'}; } else { $smax = $smin; }
if( $opt{'r'} and $opt{'r'} =~ /^\d+$/ and $opt{'r'} > 0 ){ $sinterval = $opt{'r'}; } else { $sinterval = 1; }


my $binpath = "";
if( $opt{'b'} ){ $binpath = $opt{'b'} } else { die "lacked parametor -b BINPATH . \n"; }

if( @ARGV < 1) { die "lacked parametor LOGFILEPATH .\n"; }
my $logfilepath = shift(@ARGV);


=pod
print  <<EOM;
----receivaed parametors >
----    cachesize  : $cmin to $cmax by $cinterval
----    windowsize : $wmin to $wmax by $winterval
----    thresould  : $tmin to $tmax by $tinterval
----    scopesize  : $smin to $smax by $sinterval
---- 
----    binpath    : $binpath
----    logfile    : $logfile
----
EOM
=cut



my $logfile = $logfilepath . '.4amidaSep';
my $csvfile = $logfilepath . '.amd';
my $threadfile = $logfilepath . '.threads';
my $tmpdir = $logfilepath . '.tmp';
my $actorFp = $tmpdir . '/actor.txt';

my $log2seplog = $binpath . '/log2seplog.pl';
my $log2actor = $binpath . '/log2actor2.1.pl';
my $actor2flag = $binpath . '/actor2flag2.0.pl';
my $average = $binpath . '/average.pl';
my $ratio2phase = $binpath . '/ratioPxDepP2dev2.1.pl';
#my $log2phases = $binpath . '/log2phaselogs2.1.pl';

mkdir($tmpdir, 0755) or die "can't make dir $tmpdir : $!\n";
#mkdir($phasedir, 0755) or die "can't make dir $phasedir : $!\n";

system("perl $log2seplog $logfilepath > $logfile ");

system("perl $log2actor -t $threadfile $logfile > $actorFp") ;#or die "error in $log2actor : $!\n@";




my $acterfilebw = File::ReadBackwards->new($actorFp) or die "can't open actorfile : $!\n";
my $numEvents = $acterfilebw->readline();
my $numObjects = $acterfilebw->readline();
$acterfilebw->close();
$numEvents =~ s/^\#(MethodCalls)=(\d+)\n/$2/;
$numObjects =~ s/^\#(Objects)=(\d+)\n/$2/;
if( !( $numEvents =~ /\d+/ and $numObjects =~ /\d+/ )) { die "actorfile error ( use version 2.1.x )\n"; }


open CSV, ">$csvfile" or die "can't make csv file : $!\n";
print CSV <<EOM;
<Amida>
logfile=$logfile
threadfile=$threadfile
objects=$numObjects
events=$numEvents
</Amida>
EOM
print CSV "#Cache, Window, Threshold, Scope, #phases, beginning event of phase 1, filepinter of beginning of phase 1 , ... , beginning event of phase N, file pointer of beginning of phase N, \n";


&actor2flag();

close(CSV);

unlink(<$tmpdir/*>);
rmdir($tmpdir);

print "finished.:\n closed $logfile.amd, cleaned $tmpdir.\n";

exit(0);







sub detectPhase{
	my $csize = shift;
	my $wsize = shift;
	my $tsize = $tmin;
	for( $tsize = $tmin; $tsize <= $tmax; $tsize += $tinterval ){
		detectPhaseInner($csize,$wsize,$tsize);
	}
	return;

}

sub detectPhaseInner{
	my $csize = shift;
	my $wsize = shift;
	my $tsize = shift;
	my $ssize = $smin;

	for( $ssize = $smin; $ssize <= $smax; $ssize += $sinterval ){

		open(PHASE, "perl $ratio2phase -p -s $ssize -t $tsize $tmpdir/frec_C$csize.W$wsize |" ) ;#or die "error in $ratio2phase: $!\n@";
		my @lines = <PHASE>;
		close (PHASE);
		
		my $phases = $lines[0];
		chomp($phases);
		my @eachphase = split(/,/, $phases);
		my $numPhase = @eachphase;
		if( $numPhase%2 != 0 ){ 
			pop(@eachphase);
			$numPhase = @eachphase;
		}
		$numPhase = $numPhase / 2;
		print CSV "$csize, $wsize, $tsize, $ssize, $numEvents, $numPhase, $phases\n";
		print "C$csize, W$wsize, T$tsize, M$ssize, \n";

	}
	return;
}





sub calcFrec{
	my $csize = shift;
	my $wsize = $wmin;
	for( $wsize = $wmin; $wsize <= $wmax; $wsize += $winterval ){
		system( " perl $average -c 2 -n $wsize $tmpdir/flag_C$csize > $tmpdir/frec_C$csize.W$wsize" ); #or die "error in $average : $!\n@";
		detectPhase($csize,$wsize);
	}
	return;
}





sub actor2flag{
	my $csize = $cmin;
	for( $csize = $cmin; $csize <= $cmax; $csize += $cinterval ){
		system( "perl $actor2flag -c $csize $actorFp > $tmpdir/flag_C$csize" ); #or die "error in $actor2flag : $!\n@";
		calcFrec($csize);
	}
	return;
}

