#!/usr/bin/perl
# Usage: ./bullshit_graph.pl *.spec | sort -grk2 | less
#        ./bullshit_graph.pl *.spec | sort -gk2 | tail
#        ./bullshit_graph.pl -v some.spec files.spec...
#
use Getopt::Long;
use strict;
use warnings;
our @categories = qw(█ ▒ ░);
our %factor = (
"█" => 3, # complete bullshit
"▒" => 2, # disputed claims
"░" => 1, # useless chatter
);
our @catalog = (
"█" => {qw{
	ambitious 10
	attractive 10
	deployability 10
	enterprise 10
	experience 15
	feature.compatible 10
	-grade 10
	high.performance 10
	intimidating 20
	low.latency 10
	premier 10
	production 10
	robust 10
	seamless 10
	state.of.the.art 10
	technologies 10
	technology 10
	unfortunately 20
	usability 10
}},
"▒" => {qw{
	100% 10
	comfortable 10
	comforting 10
	complete 10
	discoverable 6
	discoverability 6
	easy 10
	excellent 10
	extensible 10
	fast 10
	friendly 10
	friendlie?ness 10
	full.featured 10
	fully 10
	good 10
	handy 10
	high 10
	intelligent 10
	modern 10
	optimiz 4
	popular 15
	powerful 10
	quick 10
	quiet 10
	safely 5
	scalability 10
	scalable 10
	simple 10
	thin 6
	used.by.thousands 10
	useful 15
}},
"░" => {qw{
	Authors: 10
	MacOS 10
	MacOSX 10
	Windows 10
	aims.to 10
	anyone 10
	cross.platform 10
	designed 10
	focus 10
	focuses 10
	free 10
	intended 5
	multi.platform 10
	open 10
	scalable 10
	scaleable 10
	standard 4
	typical 4
	very 10
	working.to 10
	written.by 10
	We 40
	I\s 40
	You 5
	your 3
	\(TM\) 10
	\(R\) 10
	\(C\) 10
	™ 10
	® 10
	© 10
}},
);
our $verbose = 0;
&main();

sub slurp
{
	my $file = shift @_;
	my($fh, $desc);
	my $collect = 0;
	if (!open($fh, "< $file")) {
		warn "$file: $!";
		return;
	}
	while (defined(my $line = <$fh>)) {
		if ($line =~ /^\%description\b/) {
			$collect = 1;
			next;
		} elsif ($line =~ /^\%(package|prep|build|setup|check|install|post(un)?|pre(un)?|trigger.*|files)\b/) {
			$collect = 0;
			next;
		}
		if ($collect) {
			$desc .= $line;
		}
	}
	close($fh);
	return $desc;
}

sub analyze
{
	my($file, $text) = @_;
	my %res = (_ => 0);
	for (my $i = 0; $i < scalar(@catalog); $i += 2) {
		my $category = $catalog[$i];
		my $data = $catalog[$i+1];
		while (my($match, $points) = each %$data) {
			if ($text !~ /\b$match\b/) {
				next;
			}
			my $pts = $points * $factor{$category};
			if ($verbose) {
				print "$file /$match/ $pts\n";
			}
			$res{$category} += $pts;
			$res{_} += $pts;
		}
	}
	return \%res;
}

sub bar
{
	my($res, $width, $mostpoints) = @_;
	my $s = "";
	foreach my $cat (@categories) {
		if (!defined($res->{$cat})) {
			next;
		}
		my $rep = $width * $res->{$cat} / $mostpoints;
		$s .= $cat x $rep;
	}
	return $s;
}

sub main
{
	Getopt::Long::Configure(qw(bundling));
	&GetOptions("v" => \$verbose);
	my($filename_size, $mostpoints) = (0, 0);
	my $fh;
	my %tally;
	foreach my $file (@ARGV) {
		my $text = &slurp($file);
		$file =~ s{.*/}{}g;
		$tally{$file} = &analyze($file, $text);
		if (length($file) > $filename_size) {
			$filename_size = length($file);
		}
		if ($tally{$file}{_} > $mostpoints) {
			$mostpoints = $tally{$file}{_};
		}
	}
	my(undef, $bar_size) = split(/\s+/, `stty size 2>/dev/null`);
	if (!defined($bar_size) || $bar_size == 0) {
		$bar_size = 80;
	}
	$bar_size -= $filename_size + 2 + 4 + 2 + 1;

	while (my($file, $result) = each %tally) {
		printf("%-*s  %4u  %s\n", $filename_size, $file, $tally{$file}{_}, &bar($tally{$file}, $bar_size, $mostpoints));
	}
}
