#!/usr/bin/perl

use strict;
use warnings;
use lib './lib';

use English qw(-no_match_vars) ;
use Getopt::Long;
use Pod::Usage;
use UNIVERSAL::require;

BEGIN {

	my $libdir = "";
	if ($OSNAME eq 'MSWin32'){
		my $Registry;
		Win32::TieRegistry->require();
		Win32::TieRegistry->import(
			Delimiter   => '/',
			ArrayValues => 0,
			TiedRef     => \$Registry
		);

		my $machKey = $Registry->Open('LMachine', {
			Access => Win32::TieRegistry::KEY_READ()
		}) or die "Can't open HKEY_LOCAL_MACHINE key: $EXTENDED_OS_ERROR";

		my $uninstallValues =
			$machKey->{'SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall/FusionInventory-Agent'};
		die "FusionInventory-Agent InstallLocation registry key not found. Please install FusionInventory-Agent (2.3.17+)" unless $uninstallValues;

		my $installLocation = $uninstallValues->{'/InstallLocation'};
		die "FusionInventory-Agent InstallLocation registry key not found. Please install FusionInventory-Agent (2.3.17+)"  unless $installLocation;

		$libdir = $installLocation."\\perl\\agent\\";
		use lib "../share/armadito-agent/lib";
	}
	else{
		# Set up fusioninventory agent libdir
		my $setup = `fusioninventory-agent --setup`;
		die "fusioninventory-agent --setup not available. Please, install fusioninventory-agent (2.3.5+) before retrying." if($setup !~ /libdir: (.*?)\n/ms);
		$libdir = $1;
	}

	# If ok, we add libdir to @INC
	die "FusionInventoryAgent libs not found. Please, install fusioninventory-agent before retrying." if(! -f $libdir."/FusionInventory/Agent.pm");
	push(@INC, $libdir);
}

use Armadito::Agent;
use Armadito::Agent::Task;
use Armadito::Agent::Task::Scan;
use Armadito::Agent::Task::Scan::Armadito;
use Armadito::Agent::Task::State;
use Armadito::Agent::Task::State::Armadito;
use Armadito::Agent::Task::Alerts;
use Armadito::Agent::Task::Alerts::Armadito;
use Armadito::Agent::Task::Getjobs;
use Armadito::Agent::Task::Getjobs::Armadito;
use Armadito::Agent::Task::Runjobs;
use Armadito::Agent::Task::Runjobs::Armadito;
use Armadito::Agent::Task::Enrollment;
use Armadito::Agent::Task::Enrollment::Armadito;

my $options = {};

pod2usage(-verbose => 0, -exitstatus => 0) unless $ARGV[0];

GetOptions(
    $options,
	'server|s=s',
	'task|t=s',
	'antivirus|av=s',
	'conf-file=s',
	'conf-reload-interval=i',
	'config=s',
	'setup',
	'list-tasks',
	'list-avs',
	'help|h',
	'version|v',
) or pod2usage(-verbose => 0);

pod2usage(-verbose => 0, -exitstatus => 0) if $options->{help};

if ($options->{version}) {
    print "armadito-agent $Armadito::Agent::Task::VERSION\n";
    exit 0;
}

my %setup = (
    confdir => './etc',
    datadir => './share',
    libdir  => './lib',
    vardir  => './var',
);

if ($options->{setup}) {
    foreach my $key (keys %setup) {
        print "$key: $setup{$key}\n";
    }
    exit 0;
}

if ($options->{'conf-file'}) {
    if ($options->{config}) {
        if ($options->{config} ne 'file') {
            print STDERR
                "don't use --conf-file with $options->{config} backend";
            exit 1;
        }
    } else {
        $options->{config} = 'file';
    }
}

my $agent = Armadito::Agent->new(%setup);

if ($options->{'list-tasks'}) {
   $agent->displaySupportedTasks();
   exit 0;
}

if ($options->{'list-avs'}) {
   $agent->displaySupportedAVs();
   exit 0;
}

## default
$options->{antivirus} = "Armadito" unless(defined($options->{antivirus}));
$options->{server} = "http://armadito-glpi/glpi/plugins/armadito/" unless(defined($options->{server}));

my $config = {};

eval{
	$agent->isAVSupported($options->{antivirus}) or die "Unsupported Antivirus. Use --list-avs to see which antiviruses are supported.";
	$agent->isTaskSupported($options->{task}) or die "Unsupported Task. Use --list-tasks to see which tasks are supported.";
	$agent->isTaskUidOk($options->{task}) or die "Insufficient permissions. This task must be run as root.";
	$agent->init(options => $options);

	my $class = "Armadito::Agent::Task::$options->{task}::$options->{antivirus}";
	$class->require();
	my $task = $class->new(config => $config, agent => $agent);
	$task->run();
};

if ($EVAL_ERROR) {
    print STDERR "Execution failure:\n";
    print STDERR $EVAL_ERROR;
    exit(1);
}

exit(0);
__END__

=head1 NAME

armadito-agent - command line interface script used for Armadito Agent.

=head1 SYNOPSIS

armadito-agent --server <server> --task <task>

  Options:
    --help                 this menu

  Target definition options:
    --server server        Armadito Plugin for GLPI server URL

  Task selection options:
    --task task            Task to be executed
	--list-tasks           List supported tasks

  Antivirus selection options:
    --antivirus antivirus  Antivirus to be managed
	--list-avs             List supported antiviruses

  Configuration options:
    --config=BACKEND                   configuration backend
    --conf-file=FILE                   configuration file
    --conf-reload-interval=<SECONDS>   number of seconds between two
                                         configuration reloadings

=head1 EXAMPLES

	% armadito-agent --task "Enrollment"
	% armadito-agent -s http://armadito-glpi --task "State"
	% armadito-agent --server http://armadito-glpi --task "Getjobs"
	% armadito-agent --task "Enrollment" --conf-file /etc/myarmaditoconf.cfg

=head1 DESCRIPTION

F<armadito-agent> is the command line interface for Armadito Agent.

=head1 OPTIONS

Some options are available in a I<short> form and a I<long> form.  For
example, the two lines below are all equivalent:

    % armadito-agent -s localhost
    % armadito-agent --server localhost

=head2 Target definition options

=over

=item B<-s>, B<--server>=I<URI>

Send the results of tasks execution to given server.

In general, Armadito plugin URLs are like the following:
    http://servername/glpi/plugins/armadito/index.php

=back

=head2 Task selection options

=over

=item B<--list-tasks>

List all available tasks and exit

=item B<--task>=I<TASK>

Run given task immediately.

See option I<--list-tasks> for the list of available tasks.

=back

=head2 Antivirus selection options

=over

=item B<--list-avs>

List all available antiviruses and exit

=item B<--antivirus>=I<ANTIVIRUS>

Mange the given Antivirus

See option I<--list-avs> for the list of available antiviruses.

=back

=head2 Configuration options

=over


=item B<--config>=I<BACKEND>

Configuration backend to use.

The available backends are:

=over 4

=item

file: read configuration from a file (default anywhere else as Windows).

=item

registry: read configuration from the registry (default on Windows).

=item

none: don't read any configuration.

=back

=item B<--conf-file>=I<FILE>

Use I<FILE> as configuration file (implies file configuration backend).

=item B<--conf-reload-interval>=I<SECONDS>

SECONDS is the number of seconds between two configuration reloadings.
Default value is 0, which means that configuration is never reloaded.
Minimum value is 60. If given value is less than this minimum, it is set to
this minimum. If given value is less than 0, it is set to 0.

=back
