package Provider::Email;
#<copyright>
# ----------------------------------------------------------
# Sun Proprietary/Confidential Code
# Copyright 2001, Sun Microsystems, Inc. All rights reserved.
# ----------------------------------------------------------
#</copyright>


#  $Id: Email.pm,v 1.16 2005/03/03 17:47:29 edunning Exp $

use PDM;
use Carp;
use Message;
use Grid;
use Util;
use strict;
use MaxEvents;
use Net::SMTP;
use Filters;
use Mail;
use FSA;
use Snapshot;

use base 'Provider';
sub revision {'$Revision: 1.16 $'}

sub new {
  my($self, $pdm)  = @_;

  my($p) = { pdm => $pdm };

  bless($p,'Provider::Email');
  return $p;
}
use vars qw($SAVE_EMAIL);

sub RUN {
  my($pro, $idList) = @_;
  my($notifs, $notif, $p, $ed, $id, $cat, $sev, $admin, $eventType);
  my(%EMAILS) = (); my(%COUNT) = ();
  my($ed_desc, $email_text);
  my $edocs     = PDM->getMessagesFromList($idList);
  my($hostname) = System->hostname();

  my(%OUT);
  my $L = Labels->read('Provider')->section('email');

  my($renv, $devices, $hosts, $notifs, $Config) = PDM::ConfigFile->read();
  $DB::single = 1;

  my $timeout = $renv->{'timeout.email'} || 20;
  my($acronym) = "Storage_ADE";
  my $EMAIL_PER_EVENT = $renv->{email_per_event};   # hotmail

  my($version) = $renv->{version};

  my($st_found);
  if (System->get_stFound()) {
     $st_found = "*** $L->{diag}: " . System->get_stFound() . "\n";
  }
  my $groups = $Config->adminGroups();  # hash
  my $filters = Filters->new();
  my %LOG;

  if (System->get_testMode()) {
    $#$notifs = 0;
    if (!$renv->{test_email}) {
       Debug->print2("test_email missing in System/config, cannot test email!");
       return;
    }
    $notifs->[0]{email} = $renv->{test_email};
  }
  my $remote_only = PDM->remoteOnlyEvents();

  foreach $notif (@$notifs) {  # Each notification.
     $admin = Util->rtrim($notif->{email});
     next if ($notif->{active} eq "N");
     my $L = Labels->read('Provider')->section('email');

     $p = $notif->{priority};
     foreach $ed (@$edocs) {   # Each Message.
       next if ($ed->type() eq Message::TYPE_ALERT); # Skip alerts
       $cat    = $ed->id("category"); # A5/T3 ...
       next if ($cat =~ /^hbas/);

       my $agg_list = $ed->id("agg_list");
       next if ($ed->id("active") eq "N"); # no email if quiesced
       my $ev  = $ed->instances(0);
       $sev    = $ev->value("Severity");
       my $parent = $ev->value("Parent");
       next if ($parent  && $notif->{skip_agg});

       my $mgmtLevel  = $ev->value("MgmtLevel") ;
       next if ($mgmtLevel eq "DS");

       my $solid = $ev->value("SolutionId");
       my $solid_t =  "$L->{solid} $solid\n" if ($solid);

       my $agent    = $ed->instances(1);
       my $source   = $agent->value('IdentificationCode') if ($agent);
       my $etype0   = $ev->value('EventType');
       my @ETYPE    = split(/\./, $etype0);
       next if (index($remote_only, ",$ETYPE[1],") >= 0);
       
       my $g_code   = $ev->value("GridCode");
       my $g_no     = $ev->value("GridNo");
       my $sourceIP = $ev->value("SourceIP");
       my $caption    = $ev->value('Caption');
       my $topic      = $ev->value('DisplayTopic') || $caption || "-";
       my $comp       = $ev->value('Component');
       my $actionable = $ev->value('Actionable');
       my $target     = $ev->value('Target');
       my $fault      = $ev->value('Fault');
       my $agg        = $ev->value("Aggregate");
       my $add_to_event= 1 if ($renv->{solution} ne "N" || !$solid);

       # FILTERS
       if ($notif->{apply_filters} eq "Y") {
          my $new_sev = $filters->severity($g_no, $cat, $ev->value("Description") );
          if (defined $new_sev) {
             next if ($new_sev == 9);
             $sev = $new_sev; $actionable = "FALSE";
          }
       }

       # ADMIN-GROUP
       if ($notif->{groups}) {
         if (substr($target,0,6) eq "agent:") {
           next if (index("|$notif->{groups}|", "|SYSTEM|") < 0);
         } else {
           my($targ1,$targ2,$targ3) = split(/\:/, $target, 3);
           my $targ = "$targ1:$targ2";
           if ($groups->{$targ}) {
              next if (index("|$notif->{groups}|", "|$groups->{$targ}|") < 0);
           } elsif (!$notif->{include_ungrouped}) {
              next;
           }
         }
       }
       my $targetName =  $ev->value('TargetName') || $target;

       my $devid_t = "$L->{devid} $targetName\n" if($targetName);

       my ($last, $last_email);

       my($etype)  = $etype0;
       my($ix) = index($etype0, '.');
       $renv->{language} = $notif->{language};
       my ($gridInfo, $x);

       if ($add_to_event && $notif->{no_grid} ne "Y") {
         $gridInfo = Grid->getInfoString($etype0, $caption, $g_code);
       }

       if ($ix > 0) {
         $etype = substr($etype0, $ix+1);
         $cat   = substr($etype0, 0, $ix);
       }
       my $dev_list = lc($notif->{device});
       $dev_list =~ s/\s+/,/g;
       next if ((index($notif->{device},"*")          < 0) && 
                 index(",$dev_list,",lc(",$cat,")) < 0);

       my $run = 0;
       if ($p eq "*") {
          $run = 1;
       } elsif ($p == 91 && $actionable eq "TRUE") {
          $run = 1;
       } elsif ($p == 9 && $sev >= 1) {
          $run = 1;
       } elsif ($p == $sev) {
          $run = 1;
       }
       next if (!$run);

       $ed_desc = $ed->eventData("Description");
       my $ed_discl= $ed->eventData("Disclaimer");
       my($eid) = $ed->eventData('EventId');
       my($etime) = $ed->eventTime();
       my($data_label, $data);
       if ($ed_desc =~ /:$/) {
          $data = $ev->value("Data");
          if ($data =~ /^#INSTRUMENTATION_REPORT/) {
            $data = "";
          } else {
            my $ix2 = index($data, "\n");
            if ($ix2 > 0) {
              my $data1 = substr($data, 0, $ix2);
              if (index($ed_desc, $data1) >= 0) {
                 $data = substr($data,$ix2);
              }
            }
            $data =~ s/ \|\| /\n /g;
          }
       }
       my $ecode_line = "$L->{code} $g_no\n";
       if ($agg > 1 && $add_to_event) {
	 require EventDB;
	 my($involved, $sub, $inv_cnt) = EventDB->sub_events($agg_list, 0,  $notif->{no_grid} eq "Y");
         $data .= $involved  if ($inv_cnt > 1);
         $data .= "$L->{agg}$sub";
       }
       my $sev_txt;
       $sev_txt .= "$L->{aggregated} " if ($agg > 1 && !$fault);
       $sev_txt .= $Message::SEV_MAP{$sev} || $sev;
       my $t1;
       $t1 .= "Actionable" if ($actionable eq "TRUE");
       $t1 .= " FSA"     if ($fault);
       $sev_txt .= " ($t1)" if ($t1);

       if ($notif->{script} && -x $notif->{script} ) {
          my $dd = $ed_desc; $dd =~ s/\"//g;
          my $tt = $target || $source;
          my $com = "$notif->{script} -C \"$cat\" -G \"$g_no\" -S $sev -T \"$tt\" -N \"$targetName\" -E \"$etype.$caption\"  -D \"$dd\" -A \"$actionable\" ";
          $com .= " -I \"$sourceIP\"" if ($sourceIP);
          Util->run_command($com, "command", 20);
       }

       my $ss = ($sev >= 2) ? "E": ($sev == 1? "W":"I");
       $OUT{"${admin}:$ss"}{type} = $notif->{type};

       my $cat2 = Util->abb("$cat.medium") || uc($cat);
       my ($mydate, $mytime) = split(/ /, $etime);
       my $snapshot = System->get_snapshot();
       if ($snapshot) {
         $snapshot = "Snapshot  : $snapshot   (type=$etype0,comp=$comp, caption=$caption, code=$g_code)\n";
       }
       my $content = 
                "$L->{site} $renv->{site_name} $renv->{site_city} $renv->{site_state} \n".
                "$L->{source} $source\n"   .
                "$L->{sev} $sev_txt \n"    .
                 $L->{cat} . " $cat2\n"    .
                 $solid_t . 
		 $devid_t .
		"$L->{topic} $topic\n"   .
                "$L->{type} $etype0\n"     .
                 $ecode_line . 
		"$L->{date} $mydate\n"     .
                "$L->{time} $mytime\n$snapshot$last_email\n" .
		"$L->{discl} $ed_discl\n"  .
                "$L->{descr}\n$ed_desc\n  $gridInfo\n$data\n\n";
       $content .= "Fault: $fault\n" if ($fault && $renv->{fsa_debug});

       next if (!$admin);
       $LOG{$admin}{$targetName}++;

       if ($EMAIL_PER_EVENT) {
             my $sub = "$hostname: $cat.$etype $ed_desc";
             Mail->mail($admin, $acronym, 
                        $sub, 
                        $L->expand('requested', $hostname) .  
                            "\n$st_found\n" . $content,
                        20);
             Debug->print2("Email $etype to $admin");
       } else {
             if ($ed_discl) {
               $OUT{"${admin}:$ss"}{desc}    .= "(Service Action)";
             }
             $OUT{"${admin}:$ss"}{desc}    .= $ed_desc;
             $OUT{"${admin}:$ss"}{content} .= $content;
             $OUT{"${admin}:$ss"}{content} .= "\n" . "-" x 70 . "\n";
       }
    }
  }
  System->logHash2(\%LOG, "Notifications", "Email");

  my %S = ( W => $L->{warn}, E => $L->{err}, I => $L->{not});

  if (!$EMAIL_PER_EVENT) {
    foreach my $admin0 (keys %OUT) {
      my $type = $OUT{$admin0}{type};
      my($admin, $ss) = split(/\:/, $admin0);
      my $sev_txt = $S{$ss};

      if ($type eq "Email") {

        Debug->print1("Emailing to $admin");
        my $err = &send(0, $admin, $acronym,
                   "$sev_txt from '$hostname' ($version)",
                   $L->expand('requested', $hostname) .
                  "\n$st_found\n" . $OUT{$admin0}{content},
                   $timeout);

      } elsif ($type eq "Pager") {

        Debug->print1("Paging $admin");
        my $err = &send(1, $admin, $hostname, "", 
               substr($OUT{$admin0}{desc}, 0, 250) , $timeout);
      }
    }
  }
  Snapshot->appendFile("EMAILS", $SAVE_EMAIL);
}

sub send {
  my($pager, $to, $from, $subject, $data, $timeout) = @_;
  my $renv = System->get_renv();

  my $sendmailServer = Mail->sendmail_server();
  my $email_from     = $renv->{email_from};
  if ($email_from) {
    my $ix = index($email_from, "\@");
    $email_from = substr($email_from, $ix+1) if ($ix > 0);
  }
  my $smtp = Net::SMTP->new($sendmailServer, 
                   Timeout => $timeout, Hello => $email_from );
  if (!$smtp) {
     Debug->print2("Cannot create SMTP handle (timeout=$timeout)");
     Debug->errNoRepeat(MAIL_FAILED =>  $sendmailServer, 24);
     return;
  }
  # use utf-8 now to support all locales
  # Xuefeng Yao 2/17/2005
  my $ct = "Content-Type: text/plain; charset=utf-8";

  my $text;
  my $ef = $renv->{email_from};
  if ($ef) {
    if ($ef =~ /\@/) {
       $from = $ef;
    } else {
       $from .= "\@$ef";
    }
  }
  if ($pager) {
    $text = "From: $from\n$ct\n\n$data";
  } else {
    $text = "From: $from\nTo: $to\n$ct\nSubject: $subject\n\n$data";
  }
  $SAVE_EMAIL .= "EMAIL: $subject\n=====================================================\n$text\n";

  if ($smtp->mail($from) && $smtp->to($to)) {
     $smtp->data();
     $smtp->datasend($text);
     $smtp->dataend;
     $smtp->quit;
     return undef;
  } else {
     my $err = $smtp->message();
     $smtp->quit;
     Debug->print2("Email:send: $err");
     return $err;
  }
}
  
  
1;
