#!/usr/bin/perl
use strict;
use warnings;

my $installed = {};
my $optdeps = {};
my $name = '';
my $optdep = '';
my $provides = '';
my $type = '';

foreach my $line (split /\s*\n\s*/, `pacman -Qi`)
{
  if ($line =~ m/^Name\s+:\s+(\S+)/)
  {
    $name = $1;
    $installed->{$name} = 1;
    $type = '';
    next;
  }
  elsif ($line =~ m/^Optional Deps\s+:(\s+\S+.*)/)
  {
    $optdep = $1;
    $type = 'optdep';
  }
  elsif ($line =~ m/^\s+/ and $type eq 'optdep')
  {
    $optdep = $line;
    print "$name: $optdep\n";
  }
  elsif ($line =~ m/^Provides\s+:\s*(.*)/)
  {
    $provides = $1;
    $type = 'provides';
  }
  elsif ($line =~ m/^\s+/ and $type eq 'provides')
  {
    $provides = $line;
  }
  else
  {
    $type = '';
    next;
  }


  if ($provides ne '')
  {
    # this makes all packages provided by installed packages
    # appear as if they were installed to handle the check below
    $installed->{$_} = 1 foreach (map {&stripver($_)} grep {$_ ne 'None'} split /\s+/,$provides);
    $provides = '';
    next;
  }


  if ($optdep =~ m/^\s*(\S.*?)\s*$/)
  {
    my $line = $1;
    my ($pkg,$reason) = split /\s*:\s*/, $line;
    $reason = '' if not defined($reason);
    $pkg = &stripver($pkg);
    $optdeps->{$pkg}->{$name} = $reason if $pkg ne 'None';
  }
}

foreach my $optdep (sort keys %{$optdeps})
{
  my @pkgs = sort grep {exists($installed->{$_})} keys %{$optdeps->{$optdep}};
  if (@pkgs)
  {
    print "$optdep - optional for:\n";
    foreach my $pkg (@pkgs)
    {
      print "  $pkg: ",$optdeps->{$optdep}->{$pkg},"\n";
    }
  }
}

sub stripver
{
  my $pkg = $_[0];
  $pkg =~ s/(?:>|=|>=).+//;
  return $pkg;
}
