#!/usr/bin/perl

use strict;
use warnings;
use English;
use JSON;

my $PREFIX = defined $ARGV[0] ? "$ARGV[0]." : '';

my $SENSORS = {};
my $file = '/var/cache/ipmitool.sensors';
open my $info, $file or die "Could not open $file: $!";
while ( my $line = <$info>)  {
	# Trim whitespace
	$line =~ s/(^\s+|\s+$)//;
	# Split into columns
	my @tmp = split(/\s+\|\s+/, $line);
	next if $tmp[1] eq 'na';
	# Remap degrees units
	$tmp[2] =~ s/degrees (C|F|K)/°$1/g;
	# Map 'na' => null
	@tmp = map { $_ eq 'na' ? undef : $_ } @tmp;
	# Intial sensor object (hashref)
	$SENSORS->{$tmp[0]} = {
		'NAME'        => $tmp[0],
		'ENABLED'     => defined $tmp[1] ? 1 : 0,
		'VALUE'       => $tmp[1],
		'ENTITY'      => undef,
		'ENTITYID'    => undef,
		'CLASS'       => undef,
		'TYPE'        => undef,
		'UNITS'       => $tmp[2],
		'LOWER_FATAL' => $tmp[4],
		'LOWER_CRIT'  => $tmp[5],
		'LOWER_WARN'  => $tmp[6],
		'UPPER_WARN'  => $tmp[7],
		'UPPER_CRIT'  => $tmp[8],
		'UPPER_FATAL' => $tmp[9]
	};
}

# Fetch the Sensor Data Records for all Sensors
my @ARGS = qw(ipmitool -S /var/cache/ipmitool.sdr sdr get);
push(@ARGS, map { "'$_'" } (keys %$SENSORS));
# For each sensor
for my $sdrdata (map { s/(\r?\n)+$//m; $_ } split(/^\s*$/m, qx(@ARGS))) {
	# Parse out (<key>: <value>) pairs into a flat list
	my @parts = (map { m/^\s*(.*?)\s*:\s*(.*?)\s*$/ ? ($1, $2) : () } (split(/\r?\n/, $sdrdata)));
	# Build a hashref of {<key> => (<value-list>)} for "foo (var)" => (foo,var)
	my $data = {};
	while (@parts) {
		# Need to convert "key (thing1) : value (thing2)" to "key => (thing1, value, thing2)
		my @key = split(/(?: *[(] *| *[)] *)/, shift @parts);
		my @vals = (split(/(?: *[(] *| *[)] *)/, shift @parts));
		unshift(@vals, @key[1..$#key]);
		$data->{$key[0]} = \@vals;
	}
	# Now push the additional sensor data into out $SENSORS hashref
	my $sensor = $SENSORS->{$data->{'Sensor ID'}->[0]};
	$sensor->{'ENTITYID'} = $data->{'Entity ID'}->[0];
	$sensor->{'ENTITY'  } = $data->{'Entity ID'}->[1];
	$sensor->{'CLASS'   } = $data->{'Sensor Type'}->[0];
	$sensor->{'TYPE'    } = $data->{'Sensor Type'}->[1];
}

# Make a zabbix discovery friendly object
my $JSON = {};
$JSON->{'data'} = [];

foreach my $tmp (values %$SENSORS) {
	my @keys = map { s/(.+)/{#$PREFIX$1}/; $_ } (keys %$tmp);
	my %new = ();
	@new{@keys} = (values %$tmp);
	push(@{$JSON->{'data'}}, \%new);
}
# Doesn't really need pretty-printing, but it makes debug *much* easier
print to_json($JSON, { pretty => 1 });






