#!/usr/bin/perl

use strict;
use warnings;

use FindBin;
use lib "$FindBin::Bin/../../lib";
use Wigo::Probe qw/:all/;

use Time::HiRes qw/time/;

###
# DEFAULT CONFIG
###

my $conf = {
    'match'    => 'tap\d+|eth\d+|em\d+_\d+/\d+|em\d+_\d+|em\d+|p\d+p\d+_\d+/\d+|p\d+p\d+_\d+|p\d+p\d+|tap\d+',
    'fields'   => [ 'bytes', 'packets', 'errs', 'drop' ], # undef means all
};

init( config => $conf );
my $match = '\s+(' . config->{'match'} . '):(.*)';

###
# FETCHING STATS
###

my $now = time;
if( ! open IFSTATS, '<', '/proc/net/dev' )
{
    status  500;
    message "Error while fetching iface stats: " . $!;
    output 1;
}
my @lines = <IFSTATS>;
close IFSTATS;

###
# PARSING STATS
###

my $new = {
    'time' => $now,
};

persist or persist({});
my $delta_time = $now - persist->{'time'} if persist->{'time'};

my @fields = (
    qw/bytes packets errs drop fifo frame compressed multicast/,
    qw/bytes packets errs drop fifo colls carrier compressed/
);

my $values = {};
my @metrics;
foreach my $line ( @lines )
{
    if ( $line =~ /$match/o )
    {
        my $iface = $1;
        my @stats = split /\s+/, $2;
        shift @stats;

        for my $i ( 0..15 )
        {
            next if ( config->{'fields'} and ! grep { $fields[$i] eq $_ } @{config->{'fields'}} );
            
            my $direction = $i < 8 ? 'in' : 'out';
            
            $new->{$iface}->{$i} = $stats[$i];
            my $last = persist->{$iface};
            
            next unless $delta_time and $last;
            my $delta = ( $stats[$i] - $last->{$i} ) / $delta_time;

            # counter reset
            next if $delta < 0;

            if ( $fields[$i] eq "bytes" )
            {
                $delta = $delta * 8;
                $values->{$iface}->{$direction}->{'bytes'} = $delta;
                detail->{$iface}->{$direction}->{$fields[$i]} = sprintf "%.3f Mbps", $delta / 1024 / 1024;
            }
            else
            {
                detail->{$iface}->{$direction}->{$fields[$i]} = sprintf "%.3f/s", $delta;
            }

            add_metric { 'Tags' => { 'iface' => $iface, 'direction' => $direction,  'metric' => $fields[$i] }, 'Value' => $delta };
        }
    }
}

###
# GENERATE MESSAGE STRING
###

sub sort_iface
{
    my $total_a = 0;
    my $total_b = 0;

    $total_a += $values->{$a}->{'in'}->{'bytes'} if $values->{$a}->{'in'}->{'bytes'};
    $total_a += $values->{$a}->{'out'}->{'bytes'} if $values->{$a}->{'out'}->{'bytes'};

    $total_b += $values->{$b}->{'in'}->{'bytes'} if $values->{$b}->{'in'}->{'bytes'};
    $total_b += $values->{$b}->{'out'}->{'bytes'} if $values->{$b}->{'out'}->{'bytes'};

    return $total_b <=> $total_a;
}
my @sorted =  sort { sort_iface } keys %$values;

my @messages;
for my $iface ( splice(@sorted,0,2) )
{
    my $in  = $values->{$iface}->{'in'}->{'bytes'} / 1024 / 1024;
    my $out = $values->{$iface}->{'out'}->{'bytes'} / 1024 / 1024;
    push @messages, sprintf "%s : in %.2fMbps out %.2fMbps", ( $iface, $in, $out );
}
message join " , ", @messages if scalar @messages;

persist $new;
output 0;
