#!/usr/bin/perl

use utf8;
use strict;
use warnings;

BEGIN {
    unshift( @INC, ( $ENV{POPHOME} || '@POPHOME@' ) . '/lib' )
      unless $ENV{'KUNDE_NO_PERLPATH'};
}

use Dbase::Getopt qw(:DEFAULT);
use Dbase::Help qw(Do DoSelect qquote);
use Data::Dump qw(pp); 
use SNMP 1.8;

GetOptions(
    'debug=i' => \( my $Debug = 0 ),
    'type=s'  => \my @Type,
);

die "Sie müssen mindestens einen Typ angeben!\n" unless @Type;

my $timestamp = time();
my %Messtypen;
for my $type (@Type) {
    my $found = DoSelect {
        my ( $id, $rrd_typ, $rrd_faktor, $snmp_faktor, $oid_praefix ) = @_;
        $oid_praefix =~ s/SNMPv2-SMI::enterprises/.1.3.6.1.4.1/;

        my $messtyp = {
            id          => $id,
            rrd_typ     => $rrd_typ,
            rrd_faktor  => $rrd_faktor,
            snmp_faktor => $snmp_faktor,
            oid_praefix => $oid_praefix,
        };
        print STDERR 'Messtyp gefunden: ' . pp($messtyp) . "\n" if $Debug > 1;

        $Messtypen{$id} = $messtyp;
    }
    <<_;
SELECT id, rrd_typ, rrd_faktor, snmp_faktor, oid_praefix
  FROM mess_typ
 WHERE status = 0
   AND collectd_typ = '$type'
   AND oid_praefix IS NOT NULL
_

    die "Keinen Typ '$type' in der DB gefunden\n"
      unless $found;

}

for my $mt ( keys %Messtypen ) {
    my $messtyp = $Messtypen{$mt};

    my $old_ipkname = '';
    my $snmp_session;
    DoSelect {
        my ( $id, $oid_suffix, $ipkname, $snmp_community, $mvid ) = @_;

        my $ast = $messtyp->{oid_praefix} . $oid_suffix;
        #print STDERR "Frage Host: '$ipkname' ab!\n"
        #  if $Debug;
        if ( $old_ipkname ne $ipkname ) {
            print STDERR "Verbindung zu: '$ipkname' aufgebaut!\n" if $Debug;
            $snmp_session = new SNMP::Session(
                DestHost  => $ipkname,
                Community => $snmp_community || 'public',
                Version   => '2c',
            );
            print STDERR 'SNMP Objekt:' . pp($snmp_session) . "\n" if $Debug > 2;

            $old_ipkname = $ipkname;
        };

        if ( $snmp_session ) {
            my $wert = $snmp_session->get($ast);
            print STDERR " AST:'$ast' hat den Wert '$wert'\n" if $Debug;
            if ( defined $wert and length $wert ) {
                my $insert = <<_;
INSERT INTO mess_ablesung SET
  person = 1,
  mess_verbraucher = $mvid,
  ablesezeitpunkt  = $timestamp,
  wert = ${\qquote $wert }
_
                print STDERR "$insert" if $Debug > 2;
                my $id = Do($insert);
                print STDERR " - mess_ablessung.id = '$id'\n" if $Debug;
            }
        }
        else {
            print STDERR <<_;
WARNUNG: Konnte keine Verbindung aufbauen. Bitte Host überprüfen!
         FQDN  = '$ipkname'   MS.id = '$id'
         Ast   = '$ast'
_
        };

    } <<_;
  SELECT mess_stelle.id, mess_stelle.oid_suffix,
         ipkunde.name, ipkunde.snmp_community,
         mess_verbraucher.id
    FROM mess_stelle JOIN ipkunde ON mess_stelle.snmp_host = ipkunde.id
      JOIN mess_verbraucher ON mess_verbraucher.mess_stelle = mess_stelle.id
   WHERE typ = $messtyp->{id}
     AND ( mess_verbraucher.ende IS NULL OR mess_verbraucher.ende >= UNIX_TIMESTAMP(NOW()) )
ORDER BY ipkunde.id, mess_stelle.oid_suffix
_

}

__END__

=head1 NAME

messwert_ablesung - Liest Messwerte per SNMP ab und speichert diese in der DB

=head1 BESCHREIBUNG

Dieses Programm liest, per SNMP, für bestimmte mess_typen die Messwerte aller
Messstellen aus und speichert diese in der DB.
Die relevanten Messtypen können mittels der Kommandozeile angegeben werden.

=head1 SYNOPSE

  messwert_ablesung --type current --type work 

Liest alle Messwerte der Messstellen aus die vom Typ 'current*' oder 'work*'
sind und in der Tabelle mess_verbraucher mit Hardware verknüpft sind.

=head1 OPTIONEN

=over 4

=item -type MESSTYP

Um anzugeben, Messstellen welchen L<Messtyps> er abfragen soll.
Kann mehrfach verwendet werden, um mehrere Messtypen zu übergeben.
Der Messtyp wird anhand des collectd Typs ermittelt.

=item -debug LEVEL

Je höher der Level, desto gesprächiger das Programm.

=item -help

=item -?

um (nur) diese Dokumentation anzeigen zu lassen

=back
