#!/usr/bin/perl

use strict;

use Mysql;
use XML::DOM;
use Compress::Zlib;

print "Content-type: text/plain\n\n";

#----------------------------------------
# Parse incoming data
#----------------------------------------
my $buffer;
my %params;
my $cmd = "";

if($ENV{REQUEST_METHOD} eq 'POST')
{
    read(STDIN, $buffer, $ENV{CONTENT_LENGTH});
    $buffer = Compress::Zlib::memGunzip($buffer) if ($ENV{HTTP_X_SATIS_ENCODING} || '') =~ /gzip/; 
    $buffer .= "&";
    $buffer .= $ENV{QUERY_STRING};
} 
else
{
    $buffer = $ENV{QUERY_STRING};
}
my @pairs = split(/&/, $buffer);
my $pair;

foreach $pair(@pairs)
{
    (my $key, my $value) = split(/=/, $pair);
    $value =~ tr/+/ /;
    $value =~ s/%0D%0A/"%0A"/eg;
    $value =~ s/%([A-Fa-f0-9]{2})/pack("C",hex($1))/eg;
    
    if (defined $params{$key})
    {
        $params{$key} .= "\t$value";
    } 
    else
    {
        $params{$key} = $value;
    }
}

#--- Gereral Parameters Definition
my $opt_user="satis";
my $opt_password="satis";
my $opt_base="satis";
my $socket="/tmp/mysql.sock"; 
# Определяем используемый сокет
$ENV{"3306"}="$socket";

my $conf="/usr/local/controller/scripts/scripts.conf";
open(CONF,$conf) or die "Can't open config file!";
my $confparam="";
my $confvalue;

while(<CONF>){
    chomp();
#    print $_ . "\n";
    ($confparam,$confvalue)=split(/=/);
    if(defined($confvalue)){
        if($confparam eq "dbuser") {
	    $opt_user=$confvalue;
	}
        elsif($confparam eq "dbpass") {
	    $opt_password=$confvalue;
	}
        elsif($confparam eq "db") {
	    $opt_base=$confvalue;
	}
	else {}
    }
    else {
#	print "WARNING: split didn't find '=' in line.\n";
    }
}
close(CONF);

#--- Mysql connection 
my $dbh = Mysql->connect("", "$opt_base", "$opt_user", "$opt_password") ||
        die "Can't connect\n";
#--- End of section



my $strtoparse = $params{"xml"};
#open(FILE, "> ARMInput.xml");
#print FILE $strtoparse;
#close(FILE);
my $parser = new XML::DOM::Parser;
my $indoc = $parser->parse($strtoparse);

my $reftime = $indoc->getElementsByTagName("xml")->item(0)->getAttribute("time");

my $outdoc = new XML::DOM::Document;
my $data = $outdoc->createElement("xml");
$outdoc->appendChild($data);
$data->setAttribute("time", $reftime);

my $gets = $indoc->getElementsByTagName("get");
my $i;

for ( $i = 0; $i < $gets->getLength(); $i++)
{
  my $get = $gets->item($i);
  my $id = $get->getAttribute("id");
  my $time = $reftime + $get->getAttribute("dt");
  my $param = $get->getAttribute("param");

  my $query;
  $query = "SELECT ns.NodeID, pd.time, pd.status, pd.value, ns.Type FROM Nodes ns LEFT JOIN SystemConf sc ON ns.NodeID=sc.NodeID LEFT JOIN PollData pd ON sc.NodeID=pd.id WHERE " . ($param eq "" ? "ns.NodeID=$id" : "ns.ParentID=$id AND ns.Name='$param'") . " AND sc.Name='Active' AND sc.Value!=1 ORDER BY pd.time DESC LIMIT 1";
  my $sth = Query $dbh $query or die "$Mysql::db_errstr";

  my $new_id = $id;
  my $new_time = $time;
  my $new_status = 0;
  my $new_value = "";
  my $new_type = "";
  my $new_severity = -1;

  my $line;
  if ( $line = $sth->fetchrow_arrayref )
  {
    $new_id     = $$line[0] if $$line[0] ne "";
    $new_time   = $$line[1] if $$line[1] ne "";
    $new_status = $$line[2] if $$line[2] ne "";
    $new_value  = $$line[3] if $$line[3] ne "";
    $new_type   = $$line[4] if $$line[4] ne "";
    $new_severity = calculatePollingSeverity($new_status);

    if ( $new_type ne "Threshhold" )
    {
      my $query2 = "SELECT DISTINCT pd.status, pd.time FROM PollData pd, Nodes nd WHERE pd.id=nd.NodeID AND nd.ParentID=$id AND pd.time = (SELECT MAX(pd.time) as time FROM PollData pd, Nodes nd WHERE pd.id=nd.NodeID AND nd.ParentID=$id)";
      my $sth2 = Query $dbh $query2 or die "$Mysql::db_errstr";
      my $line2;
      while ( $line2 = $sth2->fetchrow_arrayref )
      {
        $new_status = $$line2[0] if calculatePollingSeverity($$line2[0]) > calculatePollingSeverity($new_status);
        $new_time   = $$line2[1] if $$line2[1] > $new_time;
      }
      $new_severity = calculatePollingSeverity($new_status);
      $new_status = 1 if $new_status == 3;
      $new_status = 2 if $new_status == 4;
      undef $sth2;
    }
    if ( $new_time > $time )
    {
      my $new_get = $outdoc->createElement("get");
      $data->appendChild($new_get);
      $new_get->setAttribute("id", $id);
      $new_get->setAttribute("dt", $new_time - $reftime);
      if ( $param ne "" )
      {
        $new_get->setAttribute("param", $param);
        $new_get->setAttribute("paramid", $new_id);
      }
      $new_get->setAttribute("status", $new_status);
      $new_get->setAttribute("severity", $new_severity);
      if ( $new_value ne "" )
      {
        my $cdata=$outdoc->createCDATASection("cdata");
        $cdata->setData("$new_value");
        $new_get->appendChild($cdata);
      }
    }
  }
  else
  {
    my $new_no = $outdoc->createElement("no");
    $data->appendChild($new_no);
    $new_no->setAttribute("id", $id);
    $new_no->setAttribute("param", $param) if $param ne "";
  }

  undef $sth;
}

#$outdoc->printToFile("ARMOutput.xml");
my $final = $outdoc->toString();
#$final =~  s/([^\w()'*~!.-])/sprintf '%%%02X', ord $1/eg;

sleep(2);

print $final;

$outdoc->dispose;
$indoc->dispose;

undef $dbh;

sub calculatePollingSeverity
{
  my $status = shift or 0;
  my $severity = -1;

  if ( $status == -2 ) {
    $severity = 5;
  } elsif ( $status == -1 ) {
    $severity = 5;
  } elsif ( $status == 0 ) {
    $severity = -1;
  } elsif ( $status == 1 ) {
    $severity = 3;
  } elsif ( $status == 2 ) {
    $severity = 4;
  } elsif ( $status == 3 ) {
    $severity = 3;
  } elsif ( $status == 4 ) {
    $severity = 4;
  }

  return $severity;
}
