package Registration;
use Util;
use strict;
use Agent;
use PDM;
use CIM::Instance;
use CIM::Key;
use Report;


sub RO { "remote_observation" }
sub RM { "remote_monitoring"  }
sub RN { "remote_none"        }

# Registration->ACTIVE_TYPES

sub ACTIVE_TYPES  {",6130,"}

sub EMAIL { "email"      }
sub NC    { "netconnect" }
sub MODEM { "modem"      }
sub HTTPS { "https"      }


#
# create activate/de-activate events
#
sub createEvents {
  my($class) = @_;

  return if (Util->findMaster());
  my ($renv, $devs, $hosts, $notifs)  = PDM::ConfigFile->read();
  my $LAST = "last_rasagent.conf";
  my $changed;
  my ($renv0, $devs0) = PDM::ConfigFile->read($LAST);

  # REGISTER ALL DEVICES IF ANYTHING IN THE SITE_INFO DATA HAS CHANGED.
  my($change_header);
  foreach my $e (keys %$renv) {
    #if (($e =~ /^site_/ || $e =~ /^actreg_/) &&  ($renv->{rsLevel} eq Registration::RM)) {
    if (($e =~ /^site_/ || $e =~ /^actreg_/)) {
       next if($e =~ /^actreg_contact_use_primary/);
       if ($renv->{$e} ne $renv0->{$e}) {
         $change_header = 1;
	 $changed .= "Changed $e from $renv0->{$e} to $renv->{$e}\n";
         last;
       }
    }
  }
  my ($act_cnt, $de_cnt, $act_out);
  my $hostid = System->hostid();
  my $actstring;
  my $deactstring;

  if ($renv->{solution} ne "N") {   # rack, send only one activate
     if ($change_header || ($renv->{rsLevel} ne $renv0->{rsLevel}) ) {

       my $act = ($renv->{rsLevel} eq Registration::RM) ? "activate" : "deactivate";
       $act_cnt = 1; $de_cnt = 0;
       $act_out .= "<$act>
    <device>
     <monitor_id>$hostid</monitor_id>
     <device_type>$renv->{solution}.$renv->{solution_model}</device_type>
     <device_key>$renv->{solution}:$renv->{solution_model}.$hostid</device_key>
     <serial_number>$renv->{cust_no}</serial_number>
    </device>
 </$act>";
     }
  } else {
     my $ACTIVE_TYPES = Registration->ACTIVE_TYPES;
     my(%OLD, %NEW, @activate, @deactivate);
   
     foreach my $d (@$devs0) {
        $OLD{$d->{key}} = $d;
     }
     foreach my $d (@$devs) {
        $NEW{$d->{key}} = $d;
     }
   
     if ($change_header && ($renv->{rsLevel} eq Registration::RM)) {
        foreach my $d (@$devs) {
            next if (index($ACTIVE_TYPES, ",$d->{type},") < 0);
	    my($rsLevel, $trans)   = Registration->rsLevel($d, $renv);
	    if ($rsLevel eq Registration::RM){ 
	       $actstring .= "Activating $d->{key}\n";
               push(@activate, $d);
	    }
        }
     } else {
        foreach my $d (@$devs) {
           next if (index($ACTIVE_TYPES, ",$d->{type},") < 0);
           if (!exists $OLD{$d->{key}}) {
              push(@activate, $d);
           } else {
              my($rsLevel, $trans)   = Registration->rsLevel($d, $renv);
              my($rsLevel0, $trans0) = Registration->rsLevel($OLD{$d->{key}}, $renv0);
              if ($rsLevel eq Registration::RM && $rsLevel0 ne Registration::RM) {
		 $actstring .= "Activating $d->{key}\n";
                 push(@activate, $d);
              }

              if ($rsLevel eq Registration::RO && $rsLevel0 ne Registration::RO) {
	         $deactstring .= "Deactivating $d->{key}\n";

                 push(@deactivate, $d);
              }
           }
        }
     }
   
     # LOOK FOR REMOVED DEVICES AND DEACTIVATE
     foreach my $d (@$devs0) {
        next if (index($ACTIVE_TYPES, ",$d->{type},") < 0);
        if (!exists $NEW{$d->{key}}) {
	   $deactstring .= " Deactivate $d->{key}\n";
           push(@deactivate, $d);
        }
     }
   
     foreach my $d (@activate) {
        $act_out .= &act_xml($d, "activate");
     }
     foreach my $d (@deactivate) {
        $act_out .= &act_xml($d, "deactivate");
     }
     $act_cnt= $#activate+1;
     $de_cnt = $#deactivate+1;
  }

  if (!$change_header && $act_cnt == 0 && $de_cnt == 0) {
     #PDM::ConfigFile->write( $renv, $devs, [], [], $LAST);
     return;
  }

  my $header = "<activation_user>\n" .
        &tag("contact_name", $renv->{actreg_contact_name})  .
        &tag("phone",        $renv->{actreg_contact_phone}) .
        &tag("extension",    $renv->{actreg_contact_phone_ext}) .
        &tag("email",        $renv->{actreg_contact_email}) .
        &tag("organization", $renv->{site_name}) .
        &tag("company",      $renv->{customer}) .
       "</activation_user>\n".
       "<address>\n".
        &tag("address1", $renv->{site_address})  .
        &tag("address2", $renv->{site_address2})  .
        &tag("address3", $renv->{site_address3})  .
        &tag("city",     $renv->{site_city})  .
        &tag("state",    $renv->{site_state})  .
        &tag("zipcode",  $renv->{site_zip})  .
		&tag("country",  $renv->{site_country})  .
		&tag("country_no",  $renv->{site_country_no})  .
        &tag("mailStop", $renv->{site_mailStop})  .
       "</address>\n".
       "<contact>\n".
        &tag("company",      $renv->{customer})  .
        &tag("organization", $renv->{site_name})  .
        &tag("contact_name", $renv->{site_contact})  .
        &tag("phone",        $renv->{site_phone})  .
        &tag("extension",    $renv->{site_extension})  .
        &tag("email",        $renv->{site_email})  .
       "</contact>\n";

   if ($renv->{site_contact_secondary}) {
     $header .= "<contact2>\n".
                &tag("company",      $renv->{customer})  .
                &tag("contact_name", $renv->{site_contact_secondary}) .
                &tag("phone",        $renv->{site_phone_secondary}) .
                &tag("extension",    $renv->{site_extension_secondary})  .
                &tag("email",        $renv->{site_email_secondary})  .
                "</contact2>\n";
   }
   $header .= &tag("service_level", $renv->{rsLevel} ) .
              &tag("service_transport", $renv->{transport});
              # sendmail_server may need to be added
  
   my $time = Util->get_today();

   my $xml =<<EOF;
<?xml version="1.0" encoding="UTF-8" ?>
<registration version="1.0" timestamp="$time">
$header
$act_out 
</registration>
EOF

    my($rep) = {};
    Agent::addIdentification({renv => $renv}, $rep);
    $rep = ReportContent->new($rep);

    my $act_string = "Activating $act_cnt device" . ($act_cnt>1 ? "s" : "") if ($act_cnt > 0);
    my $dact_string= "Deactivating $de_cnt device". ($de_cnt>1  ? "s" : "") if ($de_cnt > 0);
    my $comma = "," if ($act_string and $dact_string);
    my $rslevelm;
    if ($renv->{rsLevel} eq "remote_monitoring"){
        $rslevelm = "Remote Monitoring is On\n";
	if($renv->{rsLevel} ne $renv0->{rsLevel}){
           $rslevelm = "Remote Monitoring changed from Off to On\n";
        }
    }else{
       $rslevelm = "Remote Monitoring is Off\n";
       if($renv->{rsLevel} ne $renv0->{rsLevel}){
          $rslevelm = "Remote Monitoring changed from On to Off\n";
       }
    }

    Grid->setCode("agent.RegistrationEvent");
    my $ev = CIM::Instance->new('NWS_Event', [
                  [ EventType   => 'agent.RegistrationEvent'  ],
                  [ EventId     => PDM->getEventSequence  ],
                  [ Severity    => 0  ],
                  [ Caption     => "agent.registration"],
                  [ Component   => "agent"             ],
                  [ Target      => "host:$renv->{hostname}"],
                  [ Description => "$changed$rslevelm$act_string${comma}$dact_string\n$actstring$deactstring" ],
                  [ Data        => $xml ],
                   ]);
    my $sd = Events->sourceDetector({ event => $ev , host => 1, rep => $rep});

    my $pertains = CIM::Instance->new('NWS_EventPertainsToSoftwareElement', [
                  [ Event         => $ev      ],
                  [ Element       => $sd->[0] ],
                  [ DiscoveryType => "D"      ],
                    ]);
    my $ed = Message->new( { id        => { deviceName => $renv->{hostname} },
                            instances => [$ev, @$sd, $pertains ],
                            severity  => 0 });
    PDM->saveMessage($ed);
    PDM::ConfigFile->write( $renv, $devs, [], [],$LAST);
}





sub tag {
  my($tag, $v) = @_;

  return "  <$tag>" . &writeText($v) . "</$tag>\n";
}

sub writeText {
  my($text) = @_;

  # must be first;
  $text =~ s/\&/&amp;/g;

  $text =~ s/\"/&quot;/g;
  #$text =~ s/\'/&#39;/g;
  $text =~ s/</&lt;/g;
  $text =~ s/>/&gt;/g;
  $text = &cleanNonAscii($text);
  return $text;
}

sub cleanNonAscii {
  my($v) = @_;
  $v =~ s/([^\040-\176\012\015])/'{' . ord($1) . '}'/eg;
  return $v;
}


sub act_xml {
  my($d, $act) = @_;

  my $key = $d->{key};

  my @l = split(/\./, $key);

  if ($d->{fake_serial}) {
     $key = $l[$#l-2] . "." . $l[$#l-1] . ".$d->{fake_serial}";
     @l = split(/\./, $key);
  }

  my $serial = $l[$#l];

  my $hostid = System->hostid();
  return " <$act>
      <device>
        <monitor_id>$hostid</monitor_id>
        <device_type>$d->{type}.$d->{type}</device_type>
        <device_key>$d->{type}:$key</device_key>
        <serial_number>$serial</serial_number>
      </device>
  </$act>";
}


# RM or NONE only

sub rsLevel {
  my($class, $d, $renv) = @_;

  my $ACTIVE_TYPES = Registration->ACTIVE_TYPES;

  my $tr = $renv->{transport} || "na";

  if ($renv->{rsLevel} eq Registration::RN) {
     return ($renv->{rsLevel}, "na", "na");
  }

  if ($renv->{rsLevel} eq Registration::RO || index($ACTIVE_TYPES, ",$d->{type},")  < 0) {
     return (Registration::RO, $tr, "na");
  }

  if ($renv->{rsLevel} eq Registration::RM) {
     if ($d->{rsLevel} eq Registration::RO) {
        return ($d->{rsLevel}, $tr, "false");
     } else {
        return ($renv->{rsLevel}, $tr, "true");
     }
  }
  return (Registration::RN, "na", "na");
}


1;
