#!/usr/bin/perl

use warnings;
use strict;
use Getopt::Std;
use File::Basename;
use Sys::Hostname;

my %opts;

getopts('h:d:m:', \%opts);

my $sname = basename $0;
my $host = hostname;
my $level = "warning";


sub usage() {
  print STDERR <<EOU;

        usage:

        $sname -h <grid_home> -d <database_name> [ -m <address1> ]

                -h   grid_home
                -d   database
                -m   send mail alert

EOU
  exit 1;
  }

usage unless defined $opts{h} && defined $opts{d};

my (
  $key,
  $target,
  $flag,
  @instances,
  @services,
  @targets,
  @states,
  $state,
  $prefered,
  $current,
  $mailto,
  $send_mail,
  $message,
  );

if ( defined $opts{m} ) {
  $send_mail = 1;
  $mailto    = $opts{m};
  }

my ( $gh, $db ) = ( $opts{h}, $opts{d} );


open my $srvctl, "$gh/bin/srvctl config database -d $opts{d} |"
  or die "Error executing $gh/bin/srvctl config database -d $db\n";

$|++;

while ( <$srvctl> ) {
  /^Database instances:\s+(.*)/ and @instances = split /,/, $1;
  /^Services:\s+(.*)/ and @services = split /,/, $1;
  }
close $srvctl
  or warn "Error executing $gh/bin/srvctl config database -d $db:  $!\n";

# get instances status

for ( @instances ) {
  my $stat = qx|$gh/bin/srvctl status instance -d $db -i $_|;
  if ( $stat =~ /not running/ ) {
    if ( $send_mail ) {
      $message = "\n$stat\n";
      $level   = "critical";
      }
    else {
      warn "\n$stat\n";
      }
    }
  }

for my $service ( @services ) {

  # get the target
  my $oraservicename = "ora.$db.\L$service.svc";

  open my $resstate, "$gh/bin/crsctl status resource $oraservicename|"
    or warn "Cannot execute $gh/bin/srvctl status resource $oraservicename\n";

  while ( <$resstate> ) {
    /^TARGET=(.+)/ and $target  = $1;
    /^STATE=(.+)/  and $state   = $1;
    }
   
  close $resstate or warn "Close $gh/bin/srvctl status resource $oraservicename\n";	

  @targets = $target =~ /(ONLINE|OFFLINE)/g;
  @states = $state =~ /(ONLINE|OFFLINE)/g;

	
  for ( 0 .. @targets ) {
    if ( $targets[$_] ne $states[$_] ) {
      if ( $send_mail ) {
        $message .= "$service\n\ttarget: $targets[$_]\n\tstate: $states[$_]\n\n";
        }
      else {
        warn "$service\n\ttarget: $targets[$_]\n\tstate: $states[$_]\n\n";
        }
      }
    }



  open my $serviceconf, "$gh/bin/srvctl config service -d $db -s $service |"
    or warn "Cannot execute $gh/bin/srvctl config service -d $db -s $service\n";

  /Preferred instances:\s+(\S.+)/ and $prefered = $1
    while ( <$serviceconf> );

  close $serviceconf or warn "Close $gh/bin/srvctl config service -d $db -s $service\n";

  $current = qx|$gh/bin/srvctl status service -d $db -s $service|;

  chomp $current;

  if ( $current =~ /not running/ and $target eq 'ONLINE' ) {
    if ( $send_mail ) {
      $message .= $current;
      $level   = "critical";
      }
    else {
      warn "$current\n";
      }
    next;
    }

  $current =~ s/.*is running on instance\S+\s+(\S.+).*/$1/;

  if ( $current ne $prefered ) {
    if ( $send_mail ) {
      $message .= "$service is running on non prefered instance: $current\n";
      }
    else {
      warn "$service is running on non prefered instance: $current\n";
      }
    }
  }

if ( $send_mail ) {
  open my $sendmail, '| /usr/lib/sendmail -oi -t -odq'
    or die "Can't fork for sendmail: $!\n";

  print $sendmail <<EOM;
From: $ENV{'USER'}
To: $mailto
Subject: $host [$level]

$message

EOM

close $sendmail
  or warn "sendmail didn't close nicely\n";
  }

