#!/usr/bin/perl
#
# Copyright (c) 2019, AT&T Intellectual Property. All rights reserved.
#
# SPDX-License-Identifier: LGPL-2.1-only
#
use strict;
use warnings;

use Getopt::Long;
use Vyatta::Configd;
use Vyatta::Dataplane;

my @rx_stat_vars   = qw/bytes packets errors dropped overruns multicast/;
my @tx_stat_vars   = qw/bytes packets errors dropped carrier-errors collisions/;
my @port_stat_vars = qw/name vlan rx_packets rx_bytes tx_packets tx_bytes/;

my $fmt = "%12s %12s %12s %12s %12s %12s\n";

sub show_backplane_per_port {
    my ($ports) = @_;

    my @all_ports = ();
    foreach my $port ( @{$ports} ) {
        my %port_stats;

        map { $port_stats{$_} = 0 } @port_stat_vars;
        foreach my $key ( keys %{$port} ) {
            $port_stats{"$key"} = $port->{"$key"};
        }

        $port_stats { 'vlan' } = "" if ( $port_stats { 'vlan' } == 0 );
        push( @all_ports, \%port_stats );
    }

    if ( scalar @all_ports ) {
        print "\n";
        printf( $fmt,
            "Interface",
            "Vlan",
            "Rx packets",
            "RX bytes",
            "TX packets",
            "TX bytes" );
        foreach my $entry (@all_ports) {
            printf( $fmt, map { $entry->{$_} } @port_stat_vars );
        }
    }
}

sub show_backplane {
    my ( $dev, $detail ) = @_;

    my $client = Vyatta::Configd::Client->new();
    my $tree   = $client->tree_get_full_hash("interfaces backplane-state");

    my $backplanes = ( $tree->{'backplane-state'}->{'backplanes'} );

    foreach my $bp ( @{$backplanes} ) {
        my %rx_stats;
        my %tx_stats;

        next if ( $bp->{'name'} ne $dev );

        map { $rx_stats{$_} = 0 } @rx_stat_vars;
        map { $tx_stats{$_} = 0 } @tx_stat_vars;

        foreach my $key ( keys %{ $bp->{'receive-statistics'} } ) {
            $rx_stats{"$key"} = $bp->{'receive-statistics'}->{"$key"};
        }
        foreach my $key ( keys %{ $bp->{'transmit-statistics'} } ) {
            $tx_stats{"$key"} = $bp->{'transmit-statistics'}->{"$key"};
        }

        print "  Link state: $bp->{link_state}\n";
        printf( $fmt,
            "RX:  bytes", "packets", "errors",
            "ignored",    "overrun", "mcast" );
        printf( $fmt, map { $rx_stats{$_} } @rx_stat_vars );

        printf( $fmt,
            "TX:  bytes", "packets", "errors",
            "dropped",    "carrier", "collisions" );
        printf( $fmt, map { $tx_stats{$_} } @tx_stat_vars );

        show_backplane_per_port( $bp->{'port_stats'} ) if $detail;
    }
}

sub main {
    my ( $action, $dev );

    GetOptions(
        "action=s" => \$action,
        "dev=s"    => \$dev,
    ) or usage();

    usage() unless ( defined($action) );

    show_backplane( $dev, 0 ) if $action eq 'show';
    show_backplane( $dev, 1 ) if $action eq 'show-detail';
}

sub usage {
    print <<EOF;
  Usage: $0 --action show --dev <intf-name>
  Usage: $0 --action show-detail --dev <intf-name>
EOF
    exit 1;
}

main();
