#!/usr/bin/perl
#
# Copyright (c) 2019-2021, 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;
use Vyatta::InterfaceStats;

my @rx_stat_vars =
  qw/rx_bytes rx_packets rx_errors rx_dropped rx_over_errors multicast/;
my @tx_stat_vars =
  qw/tx_bytes tx_packets tx_errors tx_dropped tx_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} ) {

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

        my %clear = get_clear_stats( $dev, ( @rx_stat_vars, @tx_stat_vars ) );

        my %stats = get_intf_stats( $dev, ( @rx_stat_vars, @tx_stat_vars ) );

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

        printf( $fmt,
            "TX:  bytes", "packets", "errors",
            "dropped",    "carrier", "collisions" );
        printf( $fmt,
            map { get_counter_val( $clear{$_}, $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();
