#!/usr/bin/perl
#
# $Id$
#
# Purpose:
#     remove node record from the system
# Usage:
#     node_remove <UNI> 
#     supposed to be run by apl user (not apache!)
# Note:
#   1. The node will be removed only if down
#   2. Remove record about node from $APL/var/conf/master/<UNI>
#   3. Remove corresponded record from database (CRD)
#   4. Remove corresponded record from database (SM)

use strict;
#use Data::Dumper;
use NextCAM::Init;
use SKM::DB;
use Master::Conf;
use Log::Log4perl "get_logger";
require "$ENV{APL}/common/bin/logger.engine";


# CONS ================================================================

my $log = get_logger('NEXTCAM::CONF::NODEREMOVE');
my $uni=$ARGV[0];
my $APL=$ENV{APL};
my $MAXATTEMPT=3;
my $REBUILD_DOMAIN_ACCESS="$APL/conf/bin/rebuild_domain_access";

# VARS ------------------------------------------------------------------------
my $dbm;                                        # DB handler
my %dbs;                                        # statements
# SUBS ------------------------------------------------------------------------
sub db_master{
 eval { $dbm->disconnect() if $dbm; $dbm=''; }; # disconnect if defined
 for (my $i=1;$i<$MAXATTEMPT;$i++) {
   eval {
     $dbm=DBMaster({PrintError=>1,'RaiseError' => 1});
  };
  if($@) {
     $log->logdie("Attempt $i (final). Cannot connect to master: $@") if $i>=5;
     $log->error("Attempt $i. Cannot connect to master: $@");
     $log->error('Sleep '. $i*2 . ' before next attempt');
     die("Cannot connect") if $i==$MAXATTEMPT-1;
     sleep($i*2);
  } else {
     last;
  }
 }
 eval {
    $dbm->{FetchHashKeyName} = 'NAME_uc';
    $dbm->{ShowErrorStatement}=1;
    $dbm->{AutoCommit}=0;
    $dbs{DEL_NODE_OBJS}=$dbm->prepare(
       "update _objs set deleted=1 where node_id="
      ."(SELECT obj FROM _objs WHERE name=? AND otype='D' AND subtype='N')"
    )   or die "DEL_NODE_OBJS";
    $dbs{DEL_NODE}= $dbm->prepare(
       "update _objs set deleted=1 where name=? AND otype='D' AND subtype='N'"
    ) or die "DEL_NODE";
    $dbs{DEL_SM_NODE}= $dbm->prepare("delete from sm_nodes where nodeid=?") or die "DEL_SM_NODE";
 };
 die("Cannot prepare:$@") if $@;
 $log->debug("Connected to master db, statements prepared");
}


# MAIN ========================================================================
$log->info("[$uni] will be removed");
my $nlist=NodeList;

$log->logdie("[$uni] is unknown") if not exists $nlist->{$uni};
$log->logdie("[$uni] cannot be removed since alive at $nlist->{$uni}->{ALIVE}") if $nlist->{$uni}->{ALIVE};

eval {
 db_master();                                          # get database connection
 #---------------------------------------------------- remove from crdmng database
 #do not remove links... they should hang??
 #update _links set deleted=1 where obj_cons in
 #(select o.obj from _objs o, _objs n where n.name='$uni' and n.obj=o.node_id);
 #update _links set deleted=1 where obj_res in
 #(select o.obj from _objs o, _objs n where n.name='$uni' and n.obj=o.node_id);
 $log->info("executing DEL_NODE_OBJS $uni");
 $dbs{DEL_NODE_OBJS}->execute($uni) or die("cannot execute DEL_NODE_OBJS");
 $log->info("executing DEL_NODE $uni");
 $dbs{DEL_NODE}->execute($uni)      or die("cannot execute DEL_NODE");
 $log->info("executing DEL_SM_NODE $uni");
 $dbs{DEL_SM_NODE}->execute($uni)   or die("cannot execute DEL_SM_NODE");
 $log->info("executing COMMIT");
 $dbm->commit;
 #---------------------------------------------------- unlink flat configuration
 unlink("$APL/var/conf/master/nodes/$uni");
 #---------------------------------------------------- close access to DB for removed node
 system("$REBUILD_DOMAIN_ACCESS &>/dev/null");
};
if ($@) {
    my $err = $@;
    eval { $dbm->rollback };
    $log->logdie("[$uni] is not removed. Error $err");
}
$log->info("[$uni] has been removed");

# END =========================================================================
END {
  $dbm->disconnect() if ($dbm);   #disconnect from databases
} 

