#!/usr/bin/perl
#
# 
# (c) 2014 SUSE Linux Products GmbH, Nuremberg, Germany
# (c) 2015-2018 SUSE Linux GmbH, Nuremberg, Germany
# Author: Fabian Herschel
# License: GPL v2+
use strict;
my $Version="0.16.2018.05.09.2";
#
##################################################################
#
use POSIX;
use Sys::Syslog;
use Sys::Hostname;
use File::Path;
use Getopt::Long;
use lib '/usr/lib/SAPHanaSR-ScaleOut';
use SAPHanaSRTools;

my $ClusterNodes=0;
my $ClusterPrimaries=1;
my $ClusterSecondaries=1;

my $sid="";
my @sids;
my $ino="";
my $sortBy="";
# my $table_titleH = "Host";
my %Name;
my %Host;
my %Site;
my %Global;
my %HName;
my %SName;
my %GName;
my $help;
my $version;
my $cibFile="";
my $host = hostname();

#my $varlib='/var/lib/SAPHanaTD';
#my $testfile='SAPHanaTD.status';
#my $testcount=0;
#my $first_test=1;
my $Format="txt";
my $Continuous="no";
my $HtmlPage="/srv/www/hawk/public/SAPHanaSR/index.html";
my $Interval=10;

sub init() 
{
	my $result = GetOptions ("sid=s" => \@sids,
	                      "sort=s" => \$sortBy,
	                      "format=s" => \$Format,
	                      "cont=s" => \$Continuous,
                          "out=s" => \$HtmlPage,
                          "interval=s" => \$Interval,
                          "nodes=s" => \$ClusterNodes,
	                      "cib=s" => \$cibFile,
                          "version" => \$version,
                          "help" => \$help,
	);
    set_new_attribute_model();
    return 0;
}

#
################ BEGIN CUT - MOVE THAT TO AN PERL-LIBRARY LATER
#



sub  print_page($$$$$$$$$$$$$$$$$$$$$$$$$)
{
  my ($format, $sid, $sid_color, $hana1stat, $node1, $hana2stat, $node2, $syncstat, $syncdir, $crm_out, $crm_col, $crm_errors, $attr_out, $attr_col, $attr_errors, $score_out, $score_col, $score_errors, $log_out, $log_col, $log_errors,
     $ftd_out, $ftd_col, $ftd_errors, $check_lpa_col, $check_lpa_msg);
  $format=shift();
  $sid=shift(); $sid_color=shift();
  $hana1stat=shift(); $node1=shift(); 
  $hana2stat=shift(); $node2=shift(); 
  $syncstat=shift(); $syncdir=shift();
  $crm_out=shift(); $crm_col=shift(); $crm_errors=shift(); 
  $attr_out=shift(); $attr_col=shift(); $attr_errors=shift();
  $score_out=shift(); $score_col=shift(); $score_errors=shift();
  $log_out=shift(); $log_col=shift(); $log_errors=shift();
  $ftd_out=shift(); $ftd_col=shift(); $ftd_errors=shift();
  $check_lpa_col=shift(); $check_lpa_msg=shift();
  # in the page layout $score_col is ignored right now
  # TODO: Check id we add more and more parameters to the print_page or if we will use an hash as parameter or 
  #       id we (recover) more values here inside of the function like for the lpa values:
    my $lpa_node1=get_lpa_by_host($sid, $node1);
    my $lpa_node2=get_lpa_by_host($sid, $node2);

  my $mydate=`date`; # TODO: do it with perl ;-)
  chomp($crm_errors);
  chomp($attr_errors);
  chomp($log_errors);

  if ($format eq "txt") {
      my $syncArrow="-?-";
      my $SID=uc($sid);
      if ( $syncdir eq "right" ) { $syncArrow = "==>"; }
      if ( $syncdir eq "left" ) { $syncArrow = "<=="; }
      my $myPage = <<EOF;  
OVERALL:   $SID: $sid_color                   $mydate
SR:        $syncstat $node1 $syncArrow $node2

Cluster:   $crm_col ($crm_errors)
HANA1:     $node1 ${hana1stat}
HANA2:     $node2 ${hana2stat}

SAPHanaSR: $attr_col ($attr_errors)
LPA:       $check_lpa_col ($check_lpa_msg)
LPA:       $node1 $lpa_node1
LPA:       $node2 $lpa_node2

Syslog:    $log_col ($log_errors)
EOF
    printf( "%s\n", $myPage);
  } elsif ($format eq "html") {
  my $myPage = <<EOF;
<!DOCTYPE html>
<html lang="en">
<head>
<title>SAPHanaSR status</title>
<meta http-equiv="refresh" content="10; url=." />
<meta charset="utf-8"/>
</head>
<body class="">
<table cellpadding=5>
  <tr><td valign="top" bgcolor="$sid_color"><h2>$sid</h2></td>
      <td valign="top"><b>SAPHanaSR-monitor $mydate</b>
          <table cellpadding=1>
              <tr><td valign="top"><img width="100%" height="100%" src="final_icons/server_${hana1stat}.png"/></td>
                  <td><img width="100%" height="100%" src="final_icons/arrow_${syncdir}_${syncstat}.png"/></td>
                  <td valign="top"><img width="100%" height="100%" src="final_icons/server_${hana2stat}.png"/></td>
              </tr>
              <tr><td valign="top" align="center"><b>$node1</b></td>
                  <td valign="top" align="center"><b>$sid</b></td>
                  <td valign="top" align="center"><b>$node2</b></td>
              <tr>
          </table>
      </td>
      <td valign="top" width="5%"><img width="100%" height="100%" src="suse_logo_w-tag_color.jpg"/></td></tr>
  <tr><td valign="top" bgcolor="$crm_col"><h2>Crm</h2></td>
      <td valign="top" bgcolor="#B9B9B9"><pre>$crm_out</pre></td>
      <td valign="top" bgcolor="#B9B9B9"><pre>$crm_errors</pre></td>
  </tr>
  <tr><td valign="top" bgcolor="$attr_col" rowspan="2"><h2>Attr</h2></td>
      <td valign="top" bgcolor="#B9B9B9"><pre>$attr_out</pre></td>
      <td valign="top" bgcolor="#B9B9B9"><pre>$attr_errors</pre></td>
  </tr>
  <tr><td bgcolor="#B9B9B9"><pre>$score_out</pre></td>
      <td valign="top" bgcolor="#B9B9B9"><pre></pre></td>
  </tr>
  <tr><td valign="top" bgcolor="$log_col"><h2>Log</h2></td>
      <td valign="top" bgcolor="#B9B9B9"><pre>$log_out</pre></td>
      <td valign="top" bgcolor="#B9B9B9"><pre>$log_errors</pre></td>
  </tr>
  <tr><td valign="top" bgcolor="#B9B9B9"><h2>TD</h2></td>
      <td valign="top" bgcolor="#B9B9B9"><pre>$ftd_out</pre></td>
      <td valign="top" bgcolor="#B9B9B9"><pre></pre></td>
  </tr>
</table>
</body>
</html>
EOF
open my $HTML, ">", "$HtmlPage.new";
print $HTML $myPage;
close $HTML;
system ("mv $HtmlPage.new $HtmlPage");
  } # end html
}



my $ident = "SAPHanaSR-mon";
my $logopt = "pid";
my $facility = "LOCAL0";
my $priority = "info";

my %Colors;
$Colors{"green"}="#7AC142";
$Colors{"yellow"}="#fde944";
$Colors{"red"}="#BB0000";
$Colors{"gray"}="#B9B9B9";

openlog $ident, $logopt, $facility; 
    
if ( 0 == @sids ) {
    my $sid_ino_list;
       ( $sid_ino_list ) = get_sid_and_InstNr();
       @sids = split(",", $sid_ino_list);
}

init();
if ( $help ) {
   printf "SAPHanaSR-monitor [--sid=<sid[:instNr]>] [--cib=<OfflineCibFile>] --node=<nrnodes>\n";
   exit 0;
}
if ( $version ) {
   printf "%s\n", $Version;
   exit 0;
}

if ( $cibFile ne "" ) {
   printf "Using cib file %s\n", $cibFile;
   set_cibFile($cibFile);
}

mysyslog $priority, "%s", "Monitor startup";

sub processMonitor() {
    my $message;
    my $phost;
    my $shost;
    my $laststate="";
    #
    $sid=$sids[0];   # currently ony one sid is supported
    ( $sid, $ino ) = split(":", $sid);
    $sid=lc("$sid");
    get_hana_attributes($sid, \%Host, \%HName, \%Global, \%GName, \%Site,   \%SName);
    if ( keys(%Host) == 0 ) {
        printf "No attributes found for SID=%s\n", $sid;
        exit 1;
} 
    set_HName(\%HName);
    set_GName(\%GName);
    set_SName(\%SName);
    set_Site(\%Site);
    my $crm_out="CRM: TODO <==========="; # crm_mon -1D
    my $attr_out1=print_host_attr(\%Global, \%GName, "Global", "");
	my $attr_out2=print_host_attr(\%Site,   \%SName, "Sites",  "");
    my $attr_out3=print_host_attr(\%Host,   \%HName, "Hosts",  $sortBy);
    my $attr_out="$attr_out1\n$attr_out2\n$attr_out3";
    my $score_out="";
    my $log_out=`grep 'SAPHana.*INFO: RA' /var/log/messages | tail -20`; # TODO: Do we need to optimize the runtime of this command?
    my $ftd_out=`grep 'fhTD' /var/log/messages | tail -10`;
    my $ftd_col="gray";
    my $crm_col="green";
    my $attr_col="green";
    my $score_col="green";
    my $log_col="green";
    my $complete_col="green";

    #
    #  for the grafic output
    #
    my @node_list;
    my @msn_list;
    open my $CRM_NODES, "-|", "crm_node -l";
    while (<$CRM_NODES>) {
       if (/^[0-9]+\W+(\w+)\W/) {
       push (@node_list, $1);
       }
    }
    close $CRM_NODES;
    @node_list = (sort ( @node_list ));

    if ( $ClusterNodes < @node_list ) {
        $ClusterNodes = @node_list;
    }

    my $sync_col="green";
    my ( $first_node_name, $second_node_name ) = @node_list;
    my %hanaStatus;
    #unset %hanaStatus;
    @msn_list = get_master_nameserver();

    foreach my $thenode ( @node_list ) {
        $hanaStatus{$thenode}="grey";
        if ( check_node_status($sid, "34" , $thenode) ) { $hanaStatus{$thenode}="green"; }
        if ( check_node_status($sid, "2" , $thenode) ) { $hanaStatus{$thenode}="yellow"; }
        if ( check_node_status($sid, "1" , $thenode) ) { $hanaStatus{$thenode}="red"; }
    }
    if ( get_hana_sync_state($sid) ne "SOK" ) { $sync_col="red"; } 
    my $sync_direction="none";
    if ( check_node_mode( $sid, "P" , $msn_list[0]) && check_node_mode( $sid, "S" , $msn_list[1]) ) {
    	$sync_direction="right";
    } elsif ( check_node_mode( $sid, "S" , $msn_list[0]) && check_node_mode( $sid, "P" , $msn_list[1]) ) {
	    $sync_direction="left";
    } else  {
        $sync_direction="none";
        $sync_col="grey";
    }

    #printf "first node: %s \n", $first_node_name;
    #printf "second node: %s \n", $second_node_name;
    my $first_node_col="green";
    my $second_node_col="green";

    #
    # crm checks
    #
    my $crm_errors="";
    if ( get_nodes_online() != $ClusterNodes ) { $crm_col="yellow"; $crm_errors .= " C#n\n";}

    # attr checks
    my $attr_errors="";
    if ( get_number_primary($sid, "1234") != 1 ) { $attr_col="yellow"; $attr_errors .= " A#p"; }
    if ( get_number_primary($sid, "234") != 1 ) { $attr_col="yellow"; $attr_errors .= " A-P"; }
    if ( get_number_secondary($sid, "1234") != 1 ) { $attr_col="yellow"; $attr_errors .= " A-s";}
    if ( get_number_secondary($sid, "234") != 1 ) { $attr_col="yellow"; $attr_errors .= " A-S";}
    if ( get_number_primary($sid, "234") > 1 ) { $attr_col="red"; $attr_errors .= " A-PP";}
    if ( get_hana_sync_state($sid) ne "SOK" ) { $attr_col="yellow"; $attr_errors .= " A-SFAIL"; } 

    #printf "\n";
    
    #printf "%-16s %-16s %-16s\n", $hanaStatus{$msn_list[0]}, "$sync_direction : $sync_col", $hanaStatus{$msn_list[1]};
    #printf "%-16s %-16s %-16s\n", $msn_list[0], $sid, $msn_list[1];

    #printf "\n";
    # log checks
    my $log_errors="";
    my $check_lpa_status_col;
    my $check_lpa_msg;

    ( $check_lpa_status_col, $check_lpa_msg)=check_lpa_status($sid, $msn_list[0], $msn_list[1]);

    if ( ( $attr_col eq "yellow" ) || ( $crm_col eq "yellow" ) || 
         ( $log_col eq "yellow" ) || ( $attr_col eq "yellow" ) || 
         ( $score_col eq "yellow" ) || ( $check_lpa_status_col eq "yellow") ) 
       { $complete_col="yellow"; }
    if ( ( $attr_col eq "red" ) || ( $crm_col eq "red" ) || 
         ( $log_col eq "red" ) || ( $attr_col eq "red" ) || 
         ( $score_col eq "red" ) || ( $check_lpa_status_col eq "red")) 
       { $complete_col="red"; }
    print_page($Format,$sid, $complete_col,
               $hanaStatus{$msn_list[0]}, $msn_list[0],
               $hanaStatus{$msn_list[1]}, $msn_list[1],
               $sync_col, $sync_direction,
               $crm_out, $crm_col, $crm_errors,
               $attr_out, $attr_col, $attr_errors,
               $score_out, $attr_col, $attr_errors,
               $log_out, $log_col, $log_errors,
               $ftd_out, $ftd_col, $check_lpa_status_col, $check_lpa_msg
             );
    #
    $phost=get_host_primary($sid, "1234");
    $shost=get_host_secondary($sid, "1234");
    my ($checkOK, $failures ) = check_all_ok($sid, $ClusterNodes);
    if ( $checkOK == 0 ) {
        $message="All checks passed - primary=$phost secondary=$shost";
        mysyslog $priority, "%s", $message;
    } else {
        if ( $checkOK == 1 ) {
		$message="$checkOK check failed ($failures) - primary=$phost secondary=$shost";
        } else {
		$message="$checkOK checks failed ($failures) - primary=$phost secondary=$shost";
        }
        mysyslog $priority, "%s", $message;
    }
}
  
processMonitor();
while ( $Continuous eq "yes" ) {
    sleep $Interval;
    processMonitor();
}
 
closelog;
#
