#!/usr/bin/perl -w
# Timeout for requests.
my $timeout = 15; # the LWP default of 180 secs would be too long

use Net::Telnet ();
use EV;
use AnyEvent;
use AnyEvent::Socket;
use AnyEvent::Handle;
use AnyEvent::InfluxDB;

sub getdslstatuspage($$$) {
  my $rv1; my $rv2;
  my $hostname = shift();
  my $username = shift();
  my $password = shift();
  
  
  my $remote = new Net::Telnet (Timeout => $timeout,Errmode => 'die');
  $remote->open($hostname);
  $remote->waitfor('/Account:/');
  $remote->print($username);
  $remote->waitfor('/Password: /');
  $remote->print($password);
  $remote->waitfor('/(DrayTek|Vigor)> /');
  $remote->print("vdsl status");
  ($rv1) = $remote->waitfor('/(DrayTek|Vigor)> /');
  $remote->print("vdsl status more");
  ($rv2) = $remote->waitfor('/(DrayTek|Vigor)> /');
  
  return ($rv1.$rv2);
}

if ((@ARGV > 0) && ($ARGV[0] eq "autoconf")) {
  print("No\n");
  exit(0);
}
my $progname = $0;
my $hostname = '192.168.1.1';
my $username = 'admin';
my $password = 'admin';
my $fakehost = '';
if ($progname =~ m/([a-zA-Z0-9]+\.[a-zA-Z0-9.]+)_.+/) {
  $fakehost = $1;
  $hostname = $1;
} elsif ($progname =~ m/.+_(.+)/) {
  $hostname = $1;
}
if (defined($ENV{'hostname'})) { $hostname = $ENV{'hostname'} }
if (defined($ENV{'username'})) { $username = $ENV{'username'} }
if (defined($ENV{'password'})) { $password = $ENV{'password'} }

$dslsp = getdslstatuspage($hostname, $username, $password);
unless (defined($dslsp)) {
  exit(1);
}

# Remove non-tables, colors, table attributes and all that useless stuff
$dslsp =~ s/(<[a-zA-Z]*) (.*?)>/$1>/sg;
$dslsp =~ s|.*?<table>(.*)</table>.*|$1|sgi;
$dslsp =~ s|</{0,1}font>||g;

my $curdnrate = 'U';
my $curuprate = 'U';
my $attdnrate = 'U';
my $attuprate = 'U';
my $snrmargindn = 'U';
my $snrmarginup = 'U';
my $attenuationdn = 'U';
my $attenuationup = 'U';
my $crcerrsdn = 'U';
my $crcerrsup = 'U';
my $fecsdn = 'U';
my $fecsup = 'U';
my $esdn = 'U';
my $esup = 'U';
my $sesdn = 'U';
my $sesup = 'U';
my $lossdn = 'U';
my $lossup = 'U';
my $uasdn = 'U';
my $uasup = 'U';
my $runningmode = 'U';
my $state = 'U';

if ($dslsp =~ m!\s*Running Mode\s*:\s*([0-9][0-9][a-z,A_Z]+)\s*State\s*:\s(.*)\s* !) {
  $runningmode = $1;
  $state=$2;
}
if ($dslsp =~ m!\s*DS Attainable Rate\s*:\s*(\d+) bps\s*US Attainable Rate\s*:\s*(\d+) bps!) {
  $attdnrate = int($1);
  $attuprate = int($2);
}
if ($dslsp =~ m!\s*DS Actual Rate\s*:\s*(\d+) bps\s*US Actual Rate\s*:\s*(\d+) bps!) {
  $curdnrate = int($1);
  $curuprate = int($2);
}
if ($dslsp =~ m!\s*NE Current Attenuation\s*:\s*(\d+) dB\s*Cur SNR Margin\s*:\s*(\d+)\s+dB!) {
  $attenuationdn = $1;
  $snrmargindn = $2;
}
if ($dslsp =~ m!\s*Far Current Attenuation\s*:\s*(\d+) dB\s*Far SNR Margin\s*:\s*(\d+)\s+dB!) {
  $attenuationup = $1;
  $snrmarginup = $2;
}
if ($dslsp =~ m! CRC\s*:\s*(\d+)\s+(\d+)!) {
  $crcerrsdn = int($1);
  $crcerrsup = int($2);
}
if ($dslsp =~ m! FECS\s*:\s*(\d+)\s+(\d+)!) {
  $fecsdn = int($1);
  $fecsup = int($2);
}
if ($dslsp =~ m! ES\s*:\s*(\d+)\s+(\d+)!) {
  $esdn = int($1);
  $esup = int($2);
}
if ($dslsp =~ m! SES\s*:\s*(\d+)\s+(\d+)!) {
  $sesdn = int($1);
  $sesup = int($2);
}
if ($dslsp =~ m! LOSS\s*:\s*(\d+)\s+(\d+)!) {
  $lossdn = int($1);
  $lossup = int($2);
}
if ($dslsp =~ m! UAS\s*:\s*(\d+)\s+(\d+)!) {
  $uasdn = int($1);
  $uasup = int($2);
}

my $db = AnyEvent::InfluxDB->new(
	server		=> 'http://localhost:8086',
	username	=> 'admin',
	password	=> 'admin',
	on_request => sub {
        my ($method, $url, $post_data) = @_;
        print "$method $url\n";
        print "$post_data\n" if $post_data;
    }
);

$cv = AE::cv;
$db->write(
	database => 'Network_intern',
	data => [
		"dsl,host=$hostname attdnrate=$attdnrate,attuprate=$attuprate,curdnrate=$curdnrate,curuprate=$curuprate,snrmargindn=$snrmargindn,snrmarginup=$snrmarginup,attenuationdn=$attenuationdn,attenuationup=$attenuationup,crcerrsdn=$crcerrsdn,fecsdn=$fecsdn,esdn=$esdn,sesdn=$sesdn,lossdn=$lossdn,uasdn=$uasdn,crcerrsup=$crcerrsup,fecsup=$fecsup,esup=$esup,sesup=$sesup,lossup=$lossup,uasup=$uasup,runningmode=\"$runningmode\",state=\"$state\""
	],
	on_success => $cv,
	on_error => sub {
	$cv->croak("Failed to write data: @_");
	}
);
$cv->recv;