#!/usr/bin/perl

open(STRACEIN, '<:utf8', 'strace.out') or die('Error! Failed to open file for reading: strace.out');
open(TSVOUT, '>:utf8', 'strace.tsv') or die('Error! Failed to open file for writing: strace.tsv');
print TSVOUT "TIMESTAMP\tPID\tSYSCALL\tELAPSED\tTOTALDUR\tTOTALIO\tTOTALCPU\tARGS\tRESULT\n";

my $io_function_list = {
                        'access'=>1,
                        'chmod'=>1, 'close'=>1, 'creat'=>1,
                        'fclose'=>1, 'fcntl'=>1, 'fgetpos'=>1, 'flock'=>1, 'fseek'=>1, 'fsetpos'=>1,
                        'fstat'=>1, 'fsync'=>1, 'ftell'=>1,
                        'getdents'=>1,
                        'ioctl'=>1, # John added
                        'llseek'=>1, 'lockf'=>1, 'lseek'=>1, 'lseek64'=>1,
                        'mkdir'=>1,
                        'open'=>1,
                        'read'=>1, 'readdir'=>1, 'rename'=>1, 'rewind'=>1, 'rewinddir'=>1,
                        'scandir'=>1, 'stat'=>1, 'stat64'=>1,
                        'telldir'=>1,
                        'unlink'=>1,
                        'write'=>1
                       };

print "Converting 'strace.out' to 'strace.tsv'... ";
my $line = '';
my $total_duration = 0;
my $total_io_duration = 0;
my $total_cpu_duration = 0;
my $pid = 0;
my $start_time = 0;
while ($line = <STRACEIN>)
{
  # Garbage
  if ($line =~ /^[^\d]+(.*)$/)
  {
    $line = $1;
  }
  # PID Prefix
  if ($line =~ /^(\d+)\s+(.*)$/)
  {
    $pid = $1;
    $line = $2;
  }
  # Special Cases
  # - exit_group
  if ($line =~ /^(\d+\.\d+)\s+exit_group\(0\)\s+=\s+\?$/)
  {
  }
  # Normal Command
  elsif ($line =~/^(\d+\.\d+)\s+([a-z0-9_]+)\((.*)\)\s+=\s+(.+)\s+<(\d+\.\d+)>$/s)
  {
    my $timestamp = $1;
    my $syscall = $2;
    my $args = $3;
    my $result = $4;
    my $duration = $5;

    if ($start_time == 0)
    {
      $start_time = $timestamp;
      $timestamp = 0;
    }
    else
    {
      $timestamp = $timestamp - $start_time;
    }

    print TSVOUT sprintf("%0.6f", $timestamp) . "\t";
    print TSVOUT $pid . "\t";
    print TSVOUT $syscall . "\t";
    print TSVOUT sprintf("%0.6f", $duration) . "\t";
    print TSVOUT $args . "\t";
    print TSVOUT $result . "\n";
  }
  else
  {
    chomp($line);
    print 'Unparsed: |' . $line . "|\n";
  }
}
close(STRACEIN);
close(TSVOUT);

print "Complete!\n\n";
print " - Duration: " . $total_duration . "\n";
print " - Total IO: " . $total_io_duration . "\n";
exit;
1;
