#!/usr/bin/perl -w

use strict;
use warnings;

my $FILTERTYPE = 'xml';

my $NL = "\n";

if ($#ARGV < 1) {
    die "Filter failed! Please report bug.\n";
}

my $filename = $ARGV[0];
my $fileType  = $ARGV[1];
my $infile = $filename;

open INFILE,"< $filename";
$filename =~ s/\.tmp/\.$FILTERTYPE/;
open OUTFILE,"> $filename";


if ($fileType eq 'topology') {
    my $region = 'topo';
    my $indomain = 0;
    print OUTFILE '<node>'.$NL;

    while (<INFILE>) {

        if (/Cache Topology/) {
            $region = 'cache';
            print OUTFILE '<caches>'.$NL;
        } elsif (/NUMA Topology/) {
            print OUTFILE '</caches>'.$NL;
            print OUTFILE '<numa>'.$NL;
            $region = 'numa';
        }

        if ($region eq 'topo') {
            if (/(CPU type):\t([\w ]*)/) {
                print OUTFILE '<cpu>'.$2.'</cpu>'.$NL;
            } elsif (/CPU clock:\t([\d.]) GHz/) {
                print OUTFILE '<clock>'.$1.'</clock>'.$NL;
            } elsif (/(Sockets):\t(\d*)/) {
                print OUTFILE '<socketsPerNode>'.$2.'</socketsPerNode>'.$NL;
            } elsif (/(Cores per socket):\t(\d*)/) {
                print OUTFILE '<coresPerSocket>'.$2.'</coresPerSocket>'.$NL;
            } elsif (/(Threads per core):\t(\d*)/) {
                print OUTFILE '<threadsPerCore>'.$2.'</threadsPerCore>'.$NL;
            } elsif (/([0-9]*)\t\t([0-9]*)\t\t([0-9]*)\t\t([0-9]*)/) {
                #TODO Build tree for XML output from table!
            }
        } elsif ($region eq 'cache') {
            if (/(Size):\t([0-9]*) ([kMB]*)/) {
                my $size = $2;
                if ($3 eq 'MB') {
                    $size *= 1024;
                }
                print OUTFILE '<size>'.$size.'</size>'.$NL;
            } elsif (/(Cache groups):\t*(.*)/) {
                print OUTFILE '</cache>'.$NL;
            } elsif (/(Associativity):\t*(.*)/) {
                print OUTFILE '<associativity>'.$2.'</associativity>'.$NL;
            } elsif (/(Number of sets):\t*(.*)/) {
                print OUTFILE '<sets>'.$2.'</sets>'.$NL;
            } elsif (/(Cache line size):\t*(.*)/) {
                print OUTFILE '<linesize>'.$2.'</linesize>'.$NL;
            } elsif (/(Level):\t*(.*)/) {
                print OUTFILE '<cache>'.$NL;
                print OUTFILE '<level>'.$2.'</level>'.$NL;
            }
        } elsif ($region eq 'numa') {
            if (/Domain ([0-9]*)/) {
                if ($indomain )
                {
                    print OUTFILE '</domain>'.$NL;
                }
                print OUTFILE '<domain>'.$NL;
                print OUTFILE '<id>'.$1.'</id>'.$NL;
                $indomain = 1
            } elsif (/Memory: ([0-9.]+) MB free of total ([0-9.]+) MB/) {
                print OUTFILE '<freememory>'.$1.'</freememory>'.$NL;
                print OUTFILE '<totalmemory>'.$2.'</totalmemory>'.$NL;
            } elsif (/Processors:[ ]+([0-9. ]+)/) {
                print OUTFILE '<processors>'.$1.'</processors>'.$NL;
            }
        }
    }
    if ($indomain)
    {
        print OUTFILE '</domain>'.$NL;
    }

    print OUTFILE '</numa>'.$NL;
    print OUTFILE '</node>'.$NL;
} elsif ($fileType eq 'perfctr') {
    my $header = 0;
    my @col;
    print OUTFILE '<perfctr>'.$NL;
    while (<INFILE>) {
        if (/Event[ ]*\|[ ]*(core.*)\|/) {
            if (not $header) {
                @col = split('\|',$1);
                foreach (@col) {
                    s/core //g;
                    s/[ ]//g;
                }
                $header = 1;
            }
        }elsif (/STAT/) {

        }elsif (/\|[ ]+([A-Z0-9_]+)[ ]+\|[ ]*(.*)\|/) {
            my @rescol = split('\|',$2);
            my $id = 0;
            print OUTFILE '<result>'.$NL;
            print OUTFILE '<event>'.$1.'</event>'.$NL;
            foreach (@rescol) {
                s/[ ]//g;
                print OUTFILE '<core>'.$NL;
                print OUTFILE '<id>'.$col[$id].'</id>'.$NL;
                print OUTFILE '<value>'.$_.'</value>'.$NL;
                print OUTFILE '</core>'.$NL;
                $id++;
            }
            print OUTFILE '</result>'.$NL;
        } 
    }
    print OUTFILE '</perfctr>'.$NL;
} else {
    die "Filter failed! Unknown application type $fileType!\n";
}

#unlink($infile);
close INFILE;
close OUTFILE;

