#!/usr/bin/perl

#
# Copyright (C) Roman Dmitriev, rnd@rajven.ru
#

use utf8;
use warnings;
use Encode;
use open qw(:std :encoding(UTF-8));
no warnings 'utf8';

use English;
use FindBin '$Bin';
use lib "/opt/Eye/scripts";
use strict;
use Time::Local;
use FileHandle;
use eyelib::config;
use eyelib::database;
use eyelib::common;
use eyelib::main;
use eyelib::logconfig;
use eyelib::nagios;
use Data::Dumper;
use Time::Local;
use Date::Parse;
use Getopt::Long;
use Proc::Daemon;
use Cwd;
use File::Tail;

my $pf = '/run/hmonitor/hmonitor.pid';

my $daemon = Proc::Daemon->new(
        pid_file => $pf,
        work_dir => $HOME_DIR
);

# are you running?  Returns 0 if not.
my $pid = $daemon->Status($pf);

my $daemonize = 1;

GetOptions(
    'daemon!' => \$daemonize,
    "help"    => \&usage,
    "reload"  => \&reload,
    "restart" => \&restart,
    "start"   => \&run,
    "status"  => \&status,
    "stop"    => \&stop
) or &usage;

exit(0);

sub stop {
        if ($pid) {
                print "Stopping pid $pid...";
                if ($daemon->Kill_Daemon($pf)) {
                        print "Successfully stopped.\n";
                } else {
                        print "Could not find $pid.  Was it running?\n";
                }
         } else {
                print "Not running, nothing to stop.\n";
         }
}

sub status {
        if ($pid) {
                print "Running with pid $pid.\n";
        } else {
                print "Not running.\n";
        }
}

sub run {
if (!$pid) {
    print "Starting...";
    if ($daemonize) {
        # when Init happens, everything under it runs in the child process.
        # this is important when dealing with file handles, due to the fact
        # Proc::Daemon shuts down all open file handles when Init happens.
        # Keep this in mind when laying out your program, particularly if
        # you use filehandles.
        $daemon->Init;
        }

setpriority(0,0,19);

while(1) {
eval {

my $hdb = init_db();

#parse log
my $nagios_log=File::Tail->new(name=>$config_ref{nagios_event_socket},maxinterval=>5,interval=>1,ignore_nonexistant=>1) || die "$config_ref{nagios_event_socket} not found!";

#truncate current log file
truncate $config_ref{nagios_event_socket}, 0;

while (my $logline=$nagios_log->read) {

next unless defined $logline;
chomp($logline);

log_debug("GET:".$logline);

my ($date,$hoststate,$hoststatetype,$hostname,$hostip,$hostid,$hosttype,$svc_control)= split (/\|/, $logline);
next if (!$hostip);

if (time()-$last_refresh_config>=60) { init_option($hdb); }

if (!$svc_control) { $svc_control=0; }

if ($hoststate=~/UNREACHABLE/i) { $hoststate='DOWN'; }

my $old_state = 'HARDDOWN';

my $device;
my $auth;
my $login;
my $nagios_handler;

if (!$hostid or $hostid !~ /^[0-9]/) {
    $auth = get_record_sql($hdb,"SELECT * FROM user_auth WHERE deleted=0 AND ip=?",$hostip);
    next if (!$auth);
    $hostid = $auth->{id};
    $login = get_record_sql($hdb,'SELECT * FROM user_list WHERE id=?',$auth->{user_id});
    $device = get_record_sql($hdb,'SELECT * FROM devices WHERE user_id=?',$auth->{user_id});
    if ($auth->{nagios_status}) { $old_state = $auth->{nagios_status}; }
    db_log_verbose($hdb,"Manual host: $hostname [$hostip] => $hoststate, old: $old_state");
    } else {
    if ($hosttype=~/device/i) {
        $device = get_record_sql($hdb,'SELECT * FROM devices WHERE id=?',$hostid);
        $login = get_record_sql($hdb,'SELECT * FROM user_list WHERE id=?',$device->{user_id});
        $auth = get_record_sql($hdb,'SELECT * FROM user_auth WHERE user_id=? AND deleted=0 AND ip=?',$device->{user_id},$hostip);
        if ($device->{nagios_status}) { $old_state = $device->{nagios_status}; }
        } else {
        $auth = get_record_sql($hdb,'SELECT * FROM user_auth WHERE id=?',$hostid);
        $login = get_record_sql($hdb,'SELECT * FROM user_list WHERE id=?',$auth->{user_id});
        $device = get_record_sql($hdb,'SELECT * FROM devices WHERE user_id=?',$auth->{user_id});
        if ($auth->{nagios_status}) { $old_state = $auth->{nagios_status}; }
        }
    }

if ($auth and $auth->{nagios_handler}) { $nagios_handler=$auth->{nagios_handler}; }

db_log_debug($hdb,"Get old for $hostname [$hostip] id: $hostid type: $hosttype => state: $old_state");
if ($hoststate eq "DOWN") { $hoststate=$hoststatetype.$hoststate; }
db_log_debug($hdb,"Now for $hostname [$hostip] id: $hostid type: $hosttype => state: $hoststate");

if ($hoststate ne $old_state) {
    #disable child
    my $full_action = ($svc_control eq 2);
    #Change device state
    db_log_verbose($hdb,"Host changed! $hostname [$hostip] => $hoststate, old: $old_state");
    my $ip_aton=StrToIp($hostip);
    if ($device->{id}) { do_sql($hdb,"UPDATE devices SET nagios_status=? WHERE id=?", $hoststate, $device->{id}); }
    if ($auth->{id}) { do_sql($hdb,"UPDATE user_auth SET nagios_status=? WHERE id=?",$hoststate, $auth->{id}); }
    if ($hoststate=~/UP/i) {
        nagios_host_svc_enable($hostname,1);
        db_log_debug($hdb,"Enable notifications for host $hostname [$hostip] id: $hostid services");
        }
    if ($hoststate=~/SOFTDOWN/i) {
        if ($svc_control) {
            nagios_host_svc_disable($hostname,$full_action);
            db_log_debug($hdb,"Disable notifications for host $hostname [$hostip] id: $hostid services");
            }
        }
    if ($hoststate=~/HARDDOWN/i) {
        if ($svc_control) {
            nagios_host_svc_disable($hostname,$full_action);
            db_log_debug($hdb,"Disable notifications for host $hostname [$hostip] id: $hostid services");
            }
        if ($nagios_handler) {
            db_log_info($hdb,"Event handler $nagios_handler for $hostname [$hostip] => $hoststate found!");
            if ($nagios_handler=~/restart-port/i) {
                    my $run_cmd = $HOME_DIR."/restart_port_snmp.pl $hostip & ";
                    db_log_info($hdb,"Nagios eventhandler restart-port started for $hostname [".$hostip."]");
                    db_log_info($hdb,"Run handler: $run_cmd");
                    system($run_cmd);
                    }
            } else {
            db_log_debug($hdb,"Event handler for $hostname [$hostip] => $hoststate not found.");
            }
        }
    }
}
};
if ($@) { log_error("Exception found: $@"); sleep(60); }
}
    } else {
        log_error("Already Running with pid $pid");
    }
}

sub usage {
    print "usage: hmonitor.pl (start|stop|status|restart)\n";
    exit(0);
}

sub reload {
    print "reload process not implemented.\n";
}

sub restart {
    stop;
    run;
}
