#! /usr/bin/env perl

# parse a Belarc Advisor file to get the values out of it
# there are many more values available, but we are only getting a few

use strict;
use warnings;

my $VERSION = 0.9;
my $DATE = '20180824';

my @out;

package HTMLStrip;
use base "HTML::Parser";

sub cleanup {
   my $line = shift;
   $line =~ s/&nbsp;/ /g;
   #chomp $line;
   # ltrim only
   #$line =~ s/^\s+//;
   # rtrim only
   #$line =~ s/\s+$//;
   # trim
   $line =~ s/^\s+|\s+$//g;
   return $line;
}


sub text {
   my ( $self,$text) = @_;
   chomp $text;
   push @out, &cleanup( $text ) if $text !~ m/^\s*$/;
}

my $client = shift;

my $p = new HTMLStrip;

while (<>) {
   $p->parse($_);
}
# flush and parse remaining unparsed HTML
$p->eof;

my %definition;

#print join( "\n", @out );
my $i = 0;
while ( $i < @out ) {
   if ( $out[$i] eq 'Computer Name:' ) {
      $definition{'hostname'} = $out[++$i];
   } elsif ($out[$i] eq 'DNS Suffix:' ) {
      $definition{'dns'} = $out[++$i];
   } elsif ($out[$i] eq 'Profile Date:' ) {
      $definition{'reportdate'} = $out[++$i];
   } elsif ($out[$i] eq 'Operating System' ) {
      $definition{'os'} = $out[++$i];
   } elsif ($out[$i] eq 'Auto IP Address:' ) {
      $definition{'ip'} = $out[++$i];
      my $j = $i;
      for ( my $j = $i; $j - $i < 10; $j++ ) {
         if ( $out[$j] eq 'Physical Address:' ) {
            $definition{'mac'} = $out[$j+1];
            $i = $j;
            last;
         } # for
      } # foreach
   } elsif ($out[$i] =~ m/System Serial Number: (.*)/ ) {
      $definition{'serial'} = $1;
   } elsif ($out[$i] =~ m/Chassis Serial Number: (.*)/ ) {
      $definition{'tag'} = $1;
   } elsif ($out[$i] =~ m/Enclosure Type: (.*)/ ) {
      $definition{'enclosure'} = $1;
   } elsif ($out[$i] eq 'System Model' ) {
      $definition{'model'} = $out[++$i];
   } elsif ($out[$i] eq 'Processor' ) {
      $i += 2;
      $definition{'cpu'} = $out[$i];
   } elsif ($out[$i] eq 'Memory Modules' ) {
      $i += 2;
      $definition{'memory'} = $out[$i];
   } elsif ($out[$i] eq 'Software Licenses' ) {
      if ( $out[$i+1] eq '[' ) {
         $i += 4;
         while ( $i < @out && $out[$i] ne 'Find unused software and reduce licensing costs...' ) {
            $definition{'--' . $out[$i]} = $out[$i+1];
            $i += 2;
         }
      }
   }
   $i++;
}

# dump storage
#foreach my $key ( sort keys %definition ) {  print "$key\t$definition{$key}\n"; }

my $output;
my $temp;
my @temp;

# for several things, we need to double quote them, so we do it all at once
foreach my $toQuote ( 'os', 'os_installed', 'mac', 'serial', 'tag', 'reportdate' ) {
   $definition{$toQuote} = qq/$definition{$toQuote}/ if $definition{$toQuote};
}

# calculate system information
# clean hostname and add dns name if it exists
$definition{'hostname'} =~ m/^([a-z0-9.-]+)/;
$definition{'hostname'} = $1;
$definition{'hostname'} .= '.' . $definition{'dns'} if $definition{'dns'};
# clean memory and convert to kb
@temp = split( ' ', $definition{'memory'} );
$temp[0] *= 1024 if ( $temp[1] eq 'Megabytes' );
$definition{'memory'} = $temp[0];

# if serial not defined but tag is, set serial to tag
if ( $definition{'tag'} && ! $definition{'serial'} ) {
   $definition{'serial'} = $definition{'tag'};
   $definition{'tag'} = undef;
};

# parse cpu type, etc..
if ( $definition{'cpu'} =~ m/([0-9.]+) gigahertz (\w+) (.*)/ ) {
   $definition{'cpu_speed'} = $1 * 1024;
   $definition{'cpu_type'} = $2;
   $definition{'cpu_sub'} = $3;
}


# populate system information
$output = "system:\n";
$output .= "  hostname: $definition{hostname}\n";
$output .= "  serial: $definition{serial}\n" if $definition{'serial'};
$output .= "  tag: $definition{tag}\n" if $definition{'tag'};
$output .= "  memory: $definition{memory}\n" if $definition{'memory'};
$output .= "  cpu: $definition{cpu}\n" if $definition{'cpu'};
$output .= "  cpu_speed: $definition{cpu_speed}\n" if $definition{'cpu_speed'};
$output .= "  cpu_type: $definition{cpu_type}\n" if $definition{'cpu_type'};
$output .= "  cpu_sub: $definition{cpu_sub}\n" if $definition{'cpu_sub'};

# network information
@temp = split( '/', $definition{'ip'} );
$output .= "\nnetwork:\n  NIC:\n";
$output .= "    address: $temp[0]\n" if $temp[0];
$output .= "    netmask: $temp[1]\n" if $temp[1];
$output .= "    mac: $definition{mac}\n" if $definition{'mac'};

$output .= "\noperatingsystem:\n";
$output .= "  os_version:  \"$definition{os}\"\n" if $definition{'os'};
$output .= "  installed: $definition{os_installed}\n" if $definition{'os_installed'};

# report information
$output .= "\nreport:\n";
$output .= "  date: $definition{reportdate}\n" if $definition{'reportdate'};
$output .= "  version: 3.0.0\n";
$output .= "  client: $client\n";

# clean up YAML
$output = "#parseBelarc $VERSION YAML\n---\n" . $output . "---\n";
open REPORT,">$definition{hostname}.yaml" or die "Could not write to $definition{hostname}.yaml: $!\n";
print REPORT "$output";
close REPORT;

open SOFTWARE,">$definition{hostname}.csv" or die "Could not write to $definition{hostname}.csv: $!\n";
foreach my $key ( keys %definition ) {
   next if $key !~ m/^\-\-(.*)$/;
   my $product = $1;
   next if $key =~ m/Microsoft - PowerShell/;
   next if $key =~ m/Microsoft - Internet Explorer/;
   next if $key =~ m/Belarc - Advisor/;
   if ( $definition{$key} =~ m/\(Key: ([^)]+)/ ) { 
      $definition{$key} = $1;
   }
   print SOFTWARE "$client\t$product\t$definition{$key}\t$definition{hostname}\n";
}
close SOFTWARE;
   

#print '='x40 . "\n"; print join( "\n", @out );

