#!/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*(.*)/)
  {
    my $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
    print "$name provides shit\n";
    $installed->{$_} = 1 foreach (map {&stripver($_)} split /\s+/,$provides);
    $provides = '';
    next;
  }


  if ($optdep =~ m/^\s*(.+)\s*:\s*(.*)/)
  {
    my ($pkg,$reason) = (&stripver($1),$2);
    $optdeps->{$pkg}->{$name} = $reason;
  }
}

foreach my $optdep (sort keys %{$optdeps})
{
  if (not exists($installed->{$optdep}))
  {
    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;
}
