package Monitor::atmport;

# Author:   Thomas Aeby
#
# Author:   mrwizard@psu.edu (Joseph Gooch)
#

require 5.002;
require Exporter;

use strict;
use vars qw(@ISA @EXPORT $VERSION
            $def_timeout $def_proto $max_datasize);

use Carp;

@ISA = qw(Exporter Monitor::Monitor);
$VERSION = 2.02;

sub new
{
    my ($this,
	$host,
	$community,
	$frequency,
	$snmp
        ) = @_;
    my  $class = ref($this) || $this;
    my  $self = {};
    my %ports = {};
    my %foreports = {};
    my ($cnt,               # Count through data bytes
        $min_datasize       # Minimum data bytes required
        );

    bless($self, $class);

    croak("Must give switch host") unless $host;
    ($community="public") unless $community;
    croak("Must provide SNMP instance") unless $snmp;

    my @sub = $snmp->walk( "ASXPorts" );
    my $i;
    foreach $i (@sub) {
	#print "   walked, got $i\n" if ($BigSister::common::dl>1);
	my $pos = index( $i, ":" );
	next if( $pos<0 );
	my $soid = substr( $i, 0, $pos );
	my $val = uc(substr( $i, $pos+1 ));
	$val =~ s/^\"//;
	$val =~ s/\".*//;
	$ports{$val}="".$soid;
	$ports{"".$soid}=$val;
	print "$host Port: $val  =  Num: $soid\n" if ($BigSister::common::dl>1);
    }

    @sub=%ports;
	my ($board, $netmod, $port);
	foreach $board (1,2,3,4) {
	    foreach $netmod (1,2,3,4) {
		my (@letters) = ('A','B','C','D','E');
		foreach $port (1,2,3,4,5,6,7,8) {
		    my $text="".$board.$letters[$netmod-1].$port;
		    my $value=($board-1) * 57 + ($netmod-1) * 8 + $port - 1;
		    $foreports{$value}=$text;
		    $foreports{$text}=$value;
		}
	    }
	    foreach $netmod (5) {
		my (@letters) = ('A','B','C','D','E');
		foreach $port (1,2,3,4) {
		    my $text="".$board.$letters[$netmod-1].$port;
		    my $value=($board-1) * 57 + ($netmod-1) * 8 + $port - 1;
		    $foreports{$value}=$text;
		    $foreports{$text}=$value;
		}
	    }
	    %foreports=(%foreports, "".$board.'CTL', $board*57-1, $board*57-1, "".$board.'CTL');
	}

    $snmp->add_walk ( "ASXILMIStat" );
    $snmp->add_walk ( "ASXOperStat" );
    $snmp->add_walk ( "ASXNNIProtocol" );
    $snmp->add_walk ( "ASXds1LineStatus" );
    #$snmp->add_walk ( "ASXds3LineStatus" );

    $self->{"switch"} = $host;
    $self->{"community"} = $community;

    $self->{"ptable"} = \%ports;
    $self->{"foreptable"} = \%foreports;
    my( @bla)  = ();
    $self->{"htable"} = \@bla;

    return($self);
}


sub add_check {
    my( $self , $host, $item, $port, $vpi ) = @_;
    my( $htable ) = $self->{"htable"};
    my( $ptable ) = $self->{"ptable"};
    my( $foreptable ) = $self->{"foreptable"};

    ($item = "$host\.port") unless ($item);
    ($vpi = 0) unless($vpi);
    ($port = uc($port)) if ($port);
    print "add_check $self->{switch} using $item, $vpi, $port "  if ($BigSister::common::dl);
    ($port = 0) unless($port);
    unless ($port =~ /^[0-9]*$/) {
	if (defined $$ptable{$port}) {
	    printf "  using SNMP values" if ($BigSister::common::dl);
	    $port = $$ptable{$port};
	} elsif (defined $$foreptable{$port}) {
	    printf "  using FORE lookup" if ($BigSister::common::dl);
	    $port = $$foreptable{$port};
	} else {
	    $port = 0;
	}
    }
    print "port resolved $port \n" if ($BigSister::common::dl);

    push( @$htable, [ $host, $item, $port, $vpi ] ); 
}

sub check {
    my ($self) = @_;
}

sub late_check
{
    my ($self) = @_;
    my ( $row );
    my( $htable ) = $self->{"htable"};
    my( $ptable ) = $self->{"ptable"};
    my (%value) = ( '1' => 'up(1)',
		    '2' => 'down(2)' );   
    my (%nnivals) = ( '1' => 'none(1)',
		      '2' => 'ftpnni(2)',
		      '3' => 'forum-pnni(3)',
		      '4' => 'iisp(4)' );

    foreach $row (@$htable) {
	my ( $vars ) = $uxmon::monitor_variables{$self->{"switch"}};
	my ( $color, $probs, $text );

	my $ilmi = $vars->{"snmp.ASXILMIStat.$$row[2].$$row[3]"};
	my $oper = $vars->{"snmp.ASXOperStat.$$row[2].$$row[3]"};
	my $nni = $vars->{"snmp.ASXNNIProtocol.$$row[2].$$row[3]"};
	my ($brd,$mod,$prt) = (int($$row[2]/57), int(($$row[2]%57)/8), (($$row[2]%57)%8));
	my $ds1 = $vars->{"snmp.ASXds1LineStatus.$brd.$mod.$prt"};
	#my $ds3 = $vars->{"snmp.ASXds3LineStatus.$brd.$mod.$prt"};

	$probs = "Switch: $self->{switch}  Port: $$ptable{$$row[2]}  Vpi: $$row[3]\n";
	$text = "Switch: $self->{switch}  Port: $$ptable{$$row[2]}  Vpi: $$row[3]\n";
	$text .= "ILMI: $value{$ilmi}  State: $value{$oper}  Protocol: $nnivals{$nni}";
	if ($ilmi == 1 && $oper == 1) {
	    $color=$BigSister::common::status_codes{"green"};
	    if ($nni == 2) {
		$color=$BigSister::common::status_codes{"yellow"};
		$probs.="&yellow Connection made with ftpnni!  Please Upgrade!";
	    } else {
		$probs.="&green Connection OK";
	    }
	} elsif ($oper == 1 && $nni == 4) {
	    $color=$BigSister::common::status_codes{"green"};
	    $probs.="&green Connection OK";
	} else {
	    $color=$BigSister::common::status_codes{"red"};
	    $probs.="&red Connection down";
	}
	if (defined $ds1) {
	    my (%ds1stat) = (
		0x0001 => 'No Alarm',
		0x0002 => 'Rx PLCP Yellow Alarm',
		0x0004 => 'Tx PLCP Yellow Alarm',
		0x0008 => 'Rx PLCP LOF',
		0x0010 => 'Rx DS1 Yellow Alarm',
		0x0020 => 'Tx DS1 Yellow Alarm',
		0x0040 => 'Rx AIS Failure',
		0x0080 => 'Rx LOF Failure',
		0x0100 => 'Rx LOS Failure',
		0x0200 => 'Loopback',
		0x0400 => 'Rx Test Pattern',
		0x0800 => 'Other Failures',
		0x1000 => 'Rx Excessive CRC errors',
		0x8000 => 'Rx LCD Failure'
	    );
	    my ($warn,$panic) = (0x1636, 0x89C8);
	    $text.="\nDS1 Status: ".sprintf("%#03x",$ds1);
	    $probs.="\nSwitch: $self->{switch}  Port: $$ptable{$$row[2]}  DS1 Status: ".sprintf("%#03x",$ds1);
	    if ($ds1 & $panic) {
		$color=($color<$BigSister::common::status_codes{"red"})?$color:$BigSister::common::status_codes{"red"};
	    } elsif ($ds1 & $warn) {
		$color=($color<$BigSister::common::status_codes{"yellow"})?$color:$BigSister::common::status_codes{"yellow"};
	    } else {
		$color=($color<$BigSister::common::status_codes{"green"})?$color:$BigSister::common::status_codes{"green"};
	    }
	    foreach my $i (keys %ds1stat) {
		next unless ($ds1 & $i);

		if ($i&$panic) {
		    $probs.="\n&red $ds1stat{$i}";
		} elsif ($i&$warn) {
		    $probs.="\n&yellow $ds1stat{$i}";
		} else {
		    $probs.="\n&green $ds1stat{$i}";
		}
	    }
	}
	    
	print "$$row[1] $color $probs\n\n$text\n" if ($BigSister::common::dl>1);
	$self->report($$row[1], $color, "$probs");
	$self->report($$row[1], 101, $text);
    }
}

1;
