#!/usr/bin/perl

use strict;
use warnings;

sub find_vmcmd_cli {
	my $vmcmd_cli = -1;
	
	if(-x "/usr/bin/vmware-vim-cmd") {
		$vmcmd_cli = "/usr/bin/vmware-vim-cmd";
	}
	elsif(-x "/usr/local/bin/vmware-vim-cmd") {
		$vmcmd_cli = "/usr/local/bin/vmware-vim-cmd";
	} else {
		die "Error finding vmware-vim-cmd: $vmcmd_cli\n";
	}

	return $vmcmd_cli;
}

sub get_number_of_controllers( $ ) {
	my($tw_cli) = @_;
	my $controllers;
	my $i = 0;
	my $rc = 0;

	while($rc eq 0) {
		$i++;
		system("$tw_cli /c$i show >& /dev/null");
		$rc = $?;
	}
	$controllers = $i - 1;

	return $controllers;
}

sub get_vm_list( $ ) {
	my($vmcmd_cli) = @_;
	my @vmlist;
	my $rc;
	my $i;
	my $vmlist_output;
	my @vmlist_lines;
	my $line;

	# Get list of vm instances on server
	$vmlist_output= `$vmcmd_cli  vmsvc/getallvms`;
	$rc = $?;
	if($rc == 0) {
		# push(@vmlist,0);
	}
	@vmlist_lines= split_line($vmlist_output);

	$i= 1;
        foreach $line ( @vmlist_lines ) {
            if($i == 1) {
		# Skip header line
            }
	    else
	    {
		# Add vm id to list
		push(@vmlist, (trim(substr($line, 0, 7)), trim(substr($line, 7, 12))));
	    }
	    $i++;
        }
	return @vmlist;
}

sub get_tw_show( $$ ) {
	my($tw_cli,$controller) = @_;
	my $tw_show;

	$tw_show = `$tw_cli /c$controller show 2> /dev/null`;

	return $tw_show;
}

sub get_tw_batt( $$ ) {
	my($tw_cli,$controller) = @_;
	my($rc,$tw_batt);

	$tw_batt = `$tw_cli /c$controller/bbu show 2> /dev/null`;
	$rc = $?;
	if($rc > 0) {
		return(-1,$tw_batt);
	}
	return ($rc,$tw_batt);
}

sub get_vm_status( $$ ) {
	my($vmcmd_cli,$vmid) = @_;
	my %vm_status;
	my $vmstatus;
	
	$vmstatus= `$vmcmd_cli vmsvc/get.summary $vmid | grep overallStatus`;
	
#	my(@tw_show,@tw_batt,%unit_status,%disk_status,%batt_status,$is_batt);
#
#	@tw_show = split_line(get_tw_show($tw_cli,$controller));
#	($is_batt,@tw_batt) = get_tw_batt($tw_cli,$controller);
#
#	%unit_status = parse_unit_status(@tw_show);
#	%disk_status = parse_disk_status(@tw_show);
#
#	if($is_batt > 0) {
#		%batt_status = parse_batt_status(@tw_batt);
#	}
#
#	%controller_status = (%unit_status,%disk_status,%batt_status);
#	print($vmstatus);
	$vmstatus= substr($vmstatus, index($vmstatus, "\"")+1) ;
	$vmstatus= substr($vmstatus, 0, index($vmstatus, "\"")) ;
#	print $vmstatus;
	%vm_status= ($vmid,$vmstatus);
	return %vm_status;
}

sub parse_batt_status( @ ) {
	my(@tw_batt) = @_;

	print STDERR "Battery parser not written yet!\n";
}

sub print_hash ( % ) {
	my(%h) = @_;
	my $k;

	foreach $k (sort keys %h) {
		print "$k => $h{$k}\n";
	}
}

sub parse_unit_status( @ ) {
	my(@tw_show) = @_;
	my $line;
	my %unit_status;
	
	foreach $line ( @tw_show ) {
		if($line =~ /^(u\d)\s+.*?\s+(\w+)/) {
			$unit_status{"$1"} = "$2";
		}
	}
	return %unit_status;
}

sub parse_disk_status( @ ) {
	my(@tw_show) = @_;
	my $line;
	my %disk_status;

	foreach $line ( @tw_show ) {
		if($line =~ /^(p\d+)\s+(.*?)\s+(u\d+)/) {
			$disk_status{"$3/$1"} = "$2";
		}
	}

	return %disk_status;
}

sub split_line ( $ ) {
	my($stream) = @_;
   
	return split '\n', $stream;
}

sub rc_ok( $ ) {
	my($rc) = @_;

	return $rc;
}

sub trim($) {
  @_ = $_ if not @_ and defined wantarray;
    @_ = @_ if defined wantarray;
      for (@_ ? @_ : $_) { s/^\s+//, s/\s+$// }
        return wantarray ? @_ : $_[0] if defined wantarray;
}
	

sub rc_warn( $ ) {
	my($rc) = @_;

	if($rc < 1) {
		$rc = 1;
	}

	return $rc;
}

sub rc_crit( $ ) {
	my($rc) = @_;

	if($rc < 2) {
		$rc = 2;
	}

	return $rc;
}

sub generate_output( $$$% ) {
	my($vmid,$vmname,$output,$rc,%status) = @_;
	my $k;

	foreach $k (sort keys %status) {
		if( $status{$k} =~ /green/ ) {
		#	$output .= $vmname." is OK (vmid $k)";
			$rc = rc_ok($rc);
		}
		elsif( $status{$k} =~ /yellow/ ) {
			$output .= $vmname." is WARNING (vmid $k)";
			$rc = rc_warn($rc);
		}
		elsif( $status{$k} =~ /red/ ) {
			$output .= $vmname." is CRITICAL (vmid $k)";
			$rc = rc_warn($rc);
		}
		else
		{
			$output .= $vmname." is $status{$k}  (vmdi $k), please update check_vmware2.pl script with this case ";
			$rc = rc_crit($rc);
		}
	}

	return ($output,$rc);
}

my $vm;
my %status;
my($tw_show,$rc,$output,$controller);
$rc = 0;

my $vmcmd_cli = find_vmcmd_cli();
#my $controllers = get_number_of_controllers($tw_cli);
my @vmlist = get_vm_list($vmcmd_cli);

# my %vmids;

#foreach %vm ( @vmlist) {
#    push(%vmids, %vm);
#}

my $vmnum= @vmlist;
my @vmnames= ();

for(my $i = 0; $i < $vmnum; $i= $i+2) {
    my $vmid= $vmlist[$i];
    my $vmname= $vmlist[$i+1];
    push(@vmnames, $vmname);
    %status = get_vm_status($vmcmd_cli,$vmid);
    ($output,$rc) = generate_output($vmid,$vmname,$output,$rc,%status);
}

if( (!$output) && ($rc == 0) ) {
	$output = "All VMs OK (@vmnames)";
} elsif( (!$output) && ($rc != 0) ) {
	$output = "Something unknown happened! rc = $rc\n";
}

print "$output\n";
exit($rc);
