#!/usr/bin/perl

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

use English qw(-no_match_vars);
use Getopt::Long;
use Pod::Usage;
use XML::TreePP;

use FusionInventory::Agent::Task::NetInventory;
use FusionInventory::Agent::Tools::Hardware;
use FusionInventory::Agent::Logger;

my %types = (
    1 => 'COMPUTER',
    2 => 'NETWORKING',
    3 => 'PRINTER',
    4 => 'STORAGE',
    5 => 'POWER',
    6 => 'PHONE',
    7 => 'VIDEO',
);

my $options = {
};

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

GetOptions(
    $options,
    'model=s',
    'type=s',
    'host=s',
    'file=s',
    'community=s',
    'credentials=s',
    'entity=s',
    'timeout=i',
    'verbose',
    'debug+',
    'help',
    'version',
) or pod2usage(-verbose => 0);

if ($options->{version}) {
  print "NetInventory task $FusionInventory::Agent::Task::NetInventory::VERSION\n";
  exit 0;
}
pod2usage(-verbose => 0, -exitval => 0) if $options->{help};

pod2usage(
    -message => "no host nor file given, aborting\n", -verbose => 0
) unless $options->{host} or $options->{file};

my $device = {
    ID           => 0,
    IP           => $options->{host},
    FILE         => $options->{file},
    AUTHSNMP_ID  => 1,
    MODELSNMP_ID => 1
};

my $model       = { ID => 1 };
my $credentials = { ID => 1 };

if ($options->{model}) {
    pod2usage(
        -message => "invalid file '$options->{model}', aborting\n",
        -verbose => 0
    ) unless -f $options->{model};
    $model = loadModel($options->{model});
}

if ($options->{type}) {
    pod2usage(
        -message => "invalid type '$options->{type}', aborting\n",
        -verbose => 0
    ) unless any { $options->{type} eq $_ } values %types;
    $device->{TYPE} = $options->{type};
}

if ($options->{community}) {
    $credentials->{COMMUNITY} = $options->{community};
} elsif (defined $options->{credentials}) {
    foreach my $parameter (split(',', $options->{credentials})) {
        my ($key, $value) = split(':', $parameter);
        $key = uc($key);
        $credentials->{$key} = $value;
    }
} else {
    $credentials->{COMMUNITY} = 'public';
}

if ($options->{entity}) {
    $device = $options->{entity};
}

my $inventory = FusionInventory::Agent::Task::NetInventory->new(
    %setup,
    target => FusionInventory::Agent::Task::NetInventory::Target->new(),
    logger =>  FusionInventory::Agent::Logger->new(
        debug => $options->{debug}
    )
);

$inventory->{options} = {
    NAME => 'SNMPQUERY',
    PARAM => [
        {
            PID           => 1,
            THREADS_QUERY => 1,
            TIMEOUT       => $options->{timeout},
        }
    ],
    DEVICE         => [ $device ],
    MODEL          => [ $model ],
    AUTHENTICATION => [ $credentials ]
};

$inventory->{client} =
    FusionInventory::Agent::Task::NetInventory::Client->new(
        verbose => $options->{verbose}
    );
# TODO: need to be dropped the day we will depend on agent >= 2.3.0
$inventory->{deviceid} = 'foo';

$inventory->run();

package FusionInventory::Agent::Task::NetInventory::Client;

sub new {
    my ($class, %params) = @_;

    return bless {
        verbose => $params{verbose}
    }, $class;
}

sub send {
    my ($self, %params) = @_;

    # don't display control message by default
    return unless $self->{verbose}
        or $params{message}->{h}->{CONTENT}->{DEVICE};

    print $params{message}->getContent();
}

package FusionInventory::Agent::Task::NetInventory::Target;

sub new {
    my ($class) = @_;

    return bless {}, $class;
}

sub getUrl {
    my ($self, %params) = @_;

    ## no critic (ExplicitReturnUndef)
    return undef;
}

__END__

=head1 NAME

fusioninventory-netinventory - Standalone network inventory

=head1 SYNOPSIS

fusioninventory-netinventory [options] [--host <host>--file <file>]
  [--model <model>]

  Options:
    --host host    host to inventorize
    --file         snmpwalk output file
    --model model  XML model file
    --community    community string (default: public)
    --credentials  SNMP credentials
    --timeout val  SNMP timeout (default: 15s)
    --entity       GLPI entity
    --verbose      verbose output (control messages)
    --debug        debug output (execution traces)
    -h --help      print this message and exit
    --version      print the task version and exit

=head1 DESCRIPTION

F<fusioninventory-netinventory> allows to run a network inventory task without
a GLPI server.
