#!/usr/pkg/bin/perl

use strict;
use warnings;

use lib "/usr/pkg/share/fusioninventory/lib";
use setup;

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

use FusionInventory::Agent::Task::ESX;
use FusionInventory::Agent::Logger;
use FusionInventory::Agent::Version;

my $options = {
};

GetOptions(
    $options,
    'host=s',
    'user=s',
    'password=s',
    'directory=s',
    'tag=s',
    'help',
    'version',
    'dump',
    'dumpfile=s',
) or pod2usage(-verbose => 0);

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

if ($options->{version}) {
    my $PROVIDER = $FusionInventory::Agent::Version::PROVIDER;
    map { print $_."\n" }
        "fusioninventory-esx $FusionInventory::Agent::Task::ESX::VERSION",
        "based on $PROVIDER Agent v$FusionInventory::Agent::Version::VERSION",
        @{$FusionInventory::Agent::Version::COMMENTS};
    exit 0;
}

my $esx = FusionInventory::Agent::Task::ESX->new(
    target => {},
);

inventory_from_dump($options->{dumpfile})
    if ($options->{dumpfile});

pod2usage(-verbose => 0) unless
    $options->{host}      and
    $options->{user}      and
    $options->{password}  and
    $options->{directory};

if ($options->{dump}) {
    die "Data::Dumper perl module needed for --dump option. Please install it.\n"
        unless Data::Dumper->require();
}

if (!$esx->connect(
    host     => $options->{host},
    user     => $options->{user},
    password => $options->{password},
)) {
    die "Connection failure: ".$esx->lastError()."\n";
}

my $hasError = 0;
my $hostIds = $esx->getHostIds();
foreach my $hostId (@$hostIds) {

    my $file = write_inventory($hostId);

    next unless ($options->{dump});

    my $host = $esx->{vpbs}->getHostFullInfo($hostId);
    my $dumper = Data::Dumper->new([$host],["host"]);
    $file =~ s/\.ocs$/-hostfullinfo.dump/;

    if (open my $handle, '>', $file) {
        print $handle $dumper->Dump();
        close $handle;
        print("ESX Host full info dump saved in $file\n");
    } else {
        $hasError = 1;
        print("Can't write to $file: $ERRNO\n");
    }
}
exit($hasError);

sub write_inventory {
    my ($hostId, $file) = @_;

    my $inventory = $esx->createInventory($hostId, $options->{tag});

    $file = $options->{directory} . '/' . $inventory->getDeviceId() . ".ocs"
        unless $file;

    if (open my $handle, '>', $file) {
        my $tpp = XML::TreePP->new(indent => 2);
        print $handle $tpp->write({
            REQUEST  => {
                CONTENT  => $inventory->getContent(),
                DEVICEID => $inventory->getDeviceId(),
                QUERY    => "INVENTORY",
            }
        });

        close $handle;
        print("Inventory saved in $file\n");
    } else {
        $hasError = 1;
        print("Can't write to $file: $ERRNO\n");
    }

    return $file;
}

sub inventory_from_dump {
    my ($file) = @_;
    $file =~ s/\-hostfullinfo.dump$/.ocs/;

    die "dumpfile must be a *-hostfullinfo.dump file\n"
        if $file eq $options->{dumpfile};

    our $host ;

    do $options->{dumpfile}
        or die "Can't load $options->{dumpfile}: $!\n";

    die "Can't load host full infos from $options->{dumpfile}\n"
        unless $host;

    $esx->{vpbs} = FusionInventory::Agent::Task::ESX::Dump->new($host);

    write_inventory(undef, $file);

    exit 0;
}

package FusionInventory::Agent::Task::ESX::Dump;

sub new {
    my ($class, $fullinfo) = @_;
    return bless { _fullinfo => $fullinfo }, $class;
}

sub getHostFullInfo {
    my ($self) = @_;
    return $self->{_fullinfo};
}

__END__

=head1 NAME

fusioninventory-esx - vCenter/ESX/ESXi remote inventory from command line

=head1 SYNOPSIS

fusioninventory-esx --host <host> --user <user> --password <password> --directory <directory>

  Options:
    --help                 this menu
    --host hostname        ESX server hostname
    --user username        user name
    --password xxxx        user password
    --directory directory  output directory
    --tag tag              tag for the inventoried machine

  Advanced options:
    --dump                 also dump esx host full info datas in a *-hostfullinfo.dump file
    --dumpfile file        generate one inventory from a *-hostfullinfo.dump file

=head1 EXAMPLES

    % fusioninventory-esx --host myesx --user foo --password bar --directory /tmp


You can import the .ocs file in your inventory server with the fusioninventory-injector tool.

    %fusioninventory-injector -v --file /tmp/*.ocs -u https://example/plugins/fusioninventory/

=head1 DESCRIPTION

F<fusioninventory-esx> creates inventory of remote ESX/ESXi and vCenter VMware.
It uses the SOAP interface of the remote server.

Supported systems:

=over 4

=item F<ESX and ESXi 3.5>

=item F<ESX and ESXi 4.1>

=item F<ESXi 5.0>

=item F<vCenter 4.1>

=item F<vCenter 5.0>

=back


Active Directory users, please note the AD authentication doesn't work. You must
create a account on the VMware server.

=head1 LIMITATION

So far, ESX serial number are not collected.

=head1 SECURITY

The SSL hostname check of the server is disabled.
