package Requester::nut;

use Requester::SlowRequester;

my $oldproto_warned = {};

our( @ISA );
@ISA = qw(Requester::SlowRequester);

my $requester = new Requester::nut();

sub new {
    my ($this, $args ) = @_;
    my  $class = ref($this) || $this;
    my  $self = {};

    bless($self, $class);
    $self->TCP_port( 3493 );
    $self->register( "nut" );
    $self->{"nut.upsnames"} = {};
    $self->{"nut.upsindexes"} = {};
    return $self;
}


sub setup {
    my( $self, $srq, $gets, $indexes ) = @_;
    $self->SUPER::setup( @_ );
    $srq->{"nut.step"} = "names";
    my $host = $srq->{"nut.host"} = $self->{"env"}->{"nodeinstance"}->{"host"};
    $upsnames = $self->{"nut.upsnames"};
    $upsnames->{$host} = {} unless( defined $upsnames->{$host} );
    $upsindexes = $self->{"nut.upsindexes"};
    $upsindexes->{$host} = {} unless( defined $upsindexes->{$host} );
    $srq->{"nut.upsnames"} = $upsnames->{$host};
    $srq->{"nut.upsindexes"} = $upsindexes->{$host};
    if( $indexes ) {
        my @indexes = @$indexes;
        $srq->{"nut.indexes"} = \@indexes;
    }
}


sub do {
    my( $self, $srq ) = @_;

    while( 1 ) {
	my $step = $srq->{"nut.step"};

	if( $step eq "names" ) {
	    my $indexes = $srq->{"nut.indexes"};
	    unless( $indexes ) {
		$srq->write( "LIST UPS\n" );
		$srq->{"nut.step"} = "listups-start";
		return;
	    }
	    $srq->{"nut.step"} = "getvars-start";
	}

	if( $step eq "listups-start" ) {
	    my $line = $srq->readln();
	    return unless( $line );
	    if( $line =~ /^ERR/ ) {
		my $host = $srq->{"nut.host"};
		unless( (defined $oldproto_warned{$host}) && $oldproto_warned{$host} < time - 7200) {
		    BigSister::common::log( "err", "NUT monitoring: $host is running an ancient NUT version" );
		    $oldproto_warned{$host} = time;
		}
		$srq->status( 0, "ancient NUT version" );
	    }

	    if( $line =~ /BEGIN LIST UPS/i ) {
		$srq->{"nut.step"} = "listups-data";
		my %copy = %{$srq->{"nut.upsnames"}};
		$srq->{"nut.deletenames"} = \%copy;
	    }
	    next;
	}

	if( $step eq "listups-data" ) {
	    my $line = $srq->readln();
	    return unless( $line );
	    if( $line =~ /^UPS (.*?) / ) {
		my $ups = $1;
		delete $srq->{"nut.deletenames"}->{$ups};
		unless( defined $srq->{"nut.upsnames"}->{$ups} ) {
		    my $index = keys %{$srq->{"nut.upsnames"}};
		    $index++;
		    $srq->{"nut.upsnames"}->{$ups} = $index;
		    $srq->{"nut.upsindexes"}->{$index} = $ups;
		}	
	    }
	    elsif( $line =~ /^END LIST/ ) {
		while( my( $ups, $index ) = each %{$srq->{"nut.deletenames"}} ) {
		    delete $srq->{"nut.upsnames"}->{$ups};
		    delete $srq->{"nut.upsindexes"}->{$index};
		}
		my @index = keys %{$srq->{"nut.upsindexes"}};
		$srq->{"nut.indexes"} = \@index;
		$srq->{"nut.step"} = "getvars-start";
	    }
	    next;
	}

	if( $step eq "getvars-start" ) {
	    my $index = shift @{$srq->{"nut.indexes"}};
	    unless( defined $index ) {
	       $srq->status( 3, "finished OK" );
	       return;
	    }	
	    $srq->{"nut.index"} = $index;
	    $srq->{"nut.step"} = "listvars-start";
	    $srq->write( "LIST VAR ".($srq->{"nut.upsindexes"}->{$index})."\n" );
	    my $info = $srq->{"Test.info"};
	    $info->{$index}->{"name"} = $srq->{"nut.upsindexes"}->{$index};
	    return;
	}

	if( $step eq "listvars-start" ) {
	    my $line = $srq->readln();
	    return unless( $line );
	    if( $line =~ /^ERR/ ) {
		$srq->{"nut.step"} = "getvars-start";
	    }
	    if( $line =~ /BEGIN LIST VAR/i ) {
		$srq->{"nut.step"} = "listvars-data";
		$srq->{"nut.deletenames"} = $srq->{"nut.upsnames"};
	    }
	    next;
	}

	if( $step eq "listvars-data" ) {
	    my $line = $srq->readln();
	    return unless( $line );
	    if( $line =~ /^END/ ) {
		$srq->{"nut.step"} = "getvars-start";
	     } 
	     elsif( $line =~ /^VAR (.*?) (.*?) "(.*)"/ ) {
		 my $index = $srq->{"nut.index"};
		 my $info = $srq->{"Test.info"};
		 $info->{$index}->{$2} = $3;
	     }
	     next;
	}
    }
}
