#!/usr/bin/perl -t
# #
# Software subject to following license(s):
#   The Apache Software License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)
#   null
#

# #
# Current developer(s):
#   Luis Fernando Muñoz Mejías <Luis.Munoz@UGent.be>
#

# #
# Author(s): Germán Cancio Meliá, Marco Emilio Poleggi
#

# #
# ncm-ncd, 26.2.0, 1, Tue Apr 07 2026
#


use strict;
use warnings;

# required for CAF
BEGIN {
    unshift(@INC, '/usr/lib/perl');
    pop @INC if $INC[-1] eq '.';
}

# minimal ENV with minimal PATH
%ENV = (
    PATH => join(":", qw(/bin /usr/bin /sbin /usr/sbin)),
    HOME => "/",
);

# fix umask
umask (022);

use LC::Exception qw (SUCCESS throw_error);
use CAF::FileReader;
use NCD::ComponentProxyList;
use NCD::CLI;

use vars qw($this_app %SIG);

my $ec = LC::Exception::Context->new->will_store_errors;
$LC::Exception::Reporter = \&main::error_reporter;

# unbuffer STDOUT & STDERR
autoflush STDOUT 1;
autoflush STDERR 1;

# report exceptions here in CAF compatible way

sub error_reporter
{
    my ($err, $uncaught) = @_;
    my ($stack, $depth, $frame);
    my $report = 'error';
    $report = 'warn' unless ($err->is_error);
    if ($uncaught) {
        $this_app->$report("Uncaught exception!");
        if ($err->is_error || $this_app->option('debug') || $this_app->option('verbose')) {
            $this_app->$report("Calling stack is:");
            $stack = $err->stack;
            $depth = 0;
            while ($frame = $stack->[$depth]) {
                $this_app->report("\t", $frame->subroutine, " called at ",
                    $frame->filename, " line ", $frame->line, "\n");
                $depth++;
            }
        }
    }
    $this_app->$report($err->format, "\n");
    die("finishing...") if $err->is_error;
}

# Handle signals properly
sub signal_handler
{
    my $signal = shift;

    # ignore further signals
    $SIG{'INT'}  = 'IGNORE';
    $SIG{'TERM'} = 'IGNORE';
    $SIG{'QUIT'} = 'IGNORE';
    $SIG{'USR2'} = 'IGNORE';
    $SIG{'HUP'}  = 'IGNORE';
    $this_app->warn('signal handler: received signal: ' . $signal);
    unless ($this_app->option('noaction')) {
        # handle the signal.
        $this_app->error('ncd exiting gracefully after signal hit.');
        $this_app->finish(-1);
    }
    $this_app->finish(0);
}

$SIG{'INT'}  = \&signal_handler;
$SIG{'TERM'} = \&signal_handler;
$SIG{'QUIT'} = \&signal_handler;
$SIG{'USR2'} = \&signal_handler;
$SIG{'HUP'}  = 'IGNORE';

# initialize the ncd application
my $cmdtxt = "$0 with args ".join(',', @ARGV);
$this_app = NCD::CLI->new($0, @ARGV);
if ($this_app) {
    $this_app->debug(5, "Application started: $cmdtxt.");
    $this_app->main($ec);
} else {
    throw_error("Cannot start application ($cmdtxt).");
    exit (1);
}
