#!/usr/bin/perl -w
use strict;
use warnings;
use Getopt::Long;
use LWP::UserAgent;
use File::Basename;

my $app = basename($0);

GetOptions(
  "a|arch=s"    => \( my $arch = 'any' ),
  "d|distro=s"  => \( my $distro = 'etch' ),
  "h|help"      => \&usage,
);

my $command = shift || &usage;


my $search  = build_url($distro, $arch, $command);
my $content = get_content($search);

for ($content =~ /<tr>(.*?)<\/tr>/sg) {
  m!<a href="/$distro/(.+?)">! or next;

  my $package = $1;
  print "$package\n";
}

#----------------------------------------------------#

sub get_content {
  my $search = shift;

  my $ua = LWP::UserAgent->new;
  my $response = $ua->get($search);

  unless ($response->is_success) {
    die $response->status_line, "\n";
  }

  return $response->content;
}

#----------------------------------------------------#

sub build_url {
  my ($distro, $arch, $command) = @_;

  # TODO escape this stuff properly with URI.
  my $baseurl = 'http://packages.debian.org/search?';
  $baseurl .= "suite=$distro&arch=$arch&mode=exactfilename";
  $baseurl .= "&searchon=contents&keywords=$command";

  return $baseurl;
}

#----------------------------------------------------#

sub usage {
  print<<EOU;

$app - Copyright (c) 2008 Dean Wilson. Licensed under the GPL

This script tries to determine which packages contain the given command.
It's a rough approximation of 'yum provides <command>' - but with the
"bonus" that it uses the network.

Usage:
 $app <command>

Usage Examples:
 $app  df
 $app  -d etch du
 $app  -h # shows this information

Options:
  -d | --distro
    The distros packages to check for the command - defaults to etch.
  -a | --arch
    The architecture to check for the command - defaults to any.
  -h This help and usage information

Notes:
  This script uses http://packages.debian.org/ to determine which
  packages contain the file.

EOU
  exit 1;
}
