#!/usr/bin/perl

use strict;

use File::Basename;

my %actions = (
                  UNAME => \&processUname,
                  FIOSTATUS => \&processFioStatus,
              );

my %hostData;
my $probeName;
my $hostName;


foreach my $file (@ARGV) {
    my $fileHandle;

    open($fileHandle, "$file") || die("Unable to open file $file: $!");

    ($probeName, $hostName) = fileparse($file) =~ /^([\w]+)_([a-zA-Z\d\.]+)/;

    next if ($probeName eq "" || $hostName eq "");

    while (<$fileHandle>) {
        if (/^__BEGIN__ (\w+)/) {
            if ($actions{$1}) {
                $actions{$1}->($1, $fileHandle);
            }
        }
    }
    close($fileHandle);
}

# Dump all devices
&dumpDevices();

sub dumpDevices {
    foreach my $hostName (keys(%hostData)) {
        print "Host: $hostName\n";
        my @devices = @{$hostData{$hostName}->{device}};
        foreach my $i (0 .. $#devices) {
            print $hostName . ",";
            print $devices[$i]{model} . ",";
            print $devices[$i]{size} . ",";
            print $devices[$i]{serialNumber} . ",";
            print $devices[$i]{productNumber} . ",";
            print $devices[$i]{date} . ",";
            print $devices[$i]{firmware} . ",";
            print $devices[$i]{rev} . ",";
            print $devices[$i]{date} . ",";
            print $devices[$i]{pcieLink} . ",";
            print $devices[$i]{temp} . ",";
            print $devices[$i]{maxTemp} . ",";
            print $devices[$i]{boardTemp} . ",";
            print $devices[$i]{intVoltage} . ",";
            print $devices[$i]{intMaxVoltage} . ",";
            print $devices[$i]{auxVoltage} . ",";
            print $devices[$i]{auxMaxVoltage} . ",";
            print $devices[$i]{mediaStatus} . ",";
            print $devices[$i]{reserves} . ",";
            print $devices[$i]{bytesRead} . ",";
            print $devices[$i]{bytesWritten} . ",";
            print $devices[$i]{currentRam} . ",";
            print $devices[$i]{peakRam};
            print "\n";
        }
    }
}

sub processUname {
    my ($keyword, $fileHandle) = @_;

    while (<$fileHandle>) {
        last if (/^__END__ $keyword/);

        $hostData{$hostName}->{osType} = "Linux" if (/Linux/);
    }
}

sub processFioStatus {
    my ($keyword, $fileHandle) = @_;
    my ($adapter);
    my ($device);

    while (<$fileHandle>) {
        chomp;
        last if (/^__END__ $keyword/);

        if (/^Adapter: (.*)/) {
            $adapter = processFioAdapter($_, $fileHandle);
            push @{$hostData{$hostName}->{adapter}}, $adapter;
        }
        elsif (/^fct(.*)/) {
            $device = processFioDevice($_, $fileHandle);
            push @{$hostData{$hostName}->{device}}, $device;
        }
    }
}

sub processFioAdapter {
    my ($adapterLine, $fileHandle) = @_;
    my (%adapter) = ();

    #my ($model) = $adapterLine =~ /Adapter: (.*)/;
    #$adapter{model} = $model;

    while (<$fileHandle>) {
        last if (/^$/);
        if (/Fusion-io ([\w\s]+), Product Number: ([\w\-]+) SN:(\d+)/) {
            $adapter{model} = $1;
            $adapter{productNumber} = $2;
            $adapter{serialNumber} = $3;
        }
        elsif (/PN:([\d]+), Mfr:([\d]+), Date:(\d+)/) {
            $adapter{pn} = $1;
            $adapter{mfr} = $2;
            $adapter{date} = $3;
        }
        
    }

    return \%adapter;
}

sub processFioDevice {
    my ($deviceLine, $fileHandle) = @_;
    my (%device) = ();

    while (<$fileHandle>) {
        last if (/^$/);
        if (/Fusion-io ([\w\s]+), Product Number:([\w\-]+) SN:(\d+)/) {
            $device{model} = $1;
            $device{productNumber} = $2;
            $device{serialNumber} = $3;
        }
        elsif (/PN:([\d]+), Mfr:([\d]+), Date:(\d+)/) {
            $device{pn} = $1;
            $device{mfr} = $2;
            $device{date} = $3;
        }
        elsif (/Firmware\s+([a-z\d\.]+), rev\s+([\d]+)/) {
            $device{firmware} = $1;
            $device{rev} = $2;
        }
        elsif (/([\d\.]+) GBytes block device size/) {
            $device{size} = $1;
        }
        elsif (/([\d\.]+) MBytes block device size/) {
            $device{size} = $1/1024;
        }
        elsif (/PCIE negotiated link: (.*),/) {
            $device{pcieLink} = $1;
        }
        elsif (/Internal temperature: ([\d\.]+) degC, max ([\d\.]+) degC/) {
            $device{temp} = $1;
            $device{maxTemp} = $1;
        }
        elsif (/Board temperature: ([\d\.]+) degC/) {
            $device{boardTemp} = $1;
        }
        elsif (/Internal voltage: avg ([\d\.]+)V, max ([\d\.]+)V/) {
            $device{intVoltage} = $1;
            $device{intMaxVoltage} = $2;
        }
        elsif (/Aux voltage: avg ([\d\.]+)V, max ([\d\.]+)V/) {
            $device{auxVoltage} = $1;
            $device{auxMaxVoltage} = $2;
        }
        elsif (/Media status: ([\w\-]+);\s+Reserves: ([\d\.]+)\%/) {
            $device{mediaStatus} = $1;
            $device{reserves} = $2;
        }
        elsif (/Physical bytes written\s*:\s*([\d\,]+)/) {
            $device{bytesWritten} = $1;
            $device{bytesWritten} =~ s/,//g;
        }
        elsif (/Physical bytes read\s*:\s*([\d\,]+)/) {
            $device{bytesRead} = $1;
            $device{bytesRead} =~ s/,//g;
        }
        elsif (/Current\s*:\s*([\d\,]+)/) {
            $device{currentRam} = $1;
            $device{currentRam} =~ s/,//g;
        }
        elsif (/Peak\s*:\s*([\d\,]+)/) {
            $device{peakRam} = $1;
            $device{peakRam} =~ s/,//g;
        }
        
    }

    return \%device;
}

