#!/usr/bin/perl

use strict;
use utf8;
use LWP::UserAgent;

use Getopt::Std;

my ($version) = '$Revision: 129 $' =~ /Revision:\s*(.+?)\s*\$/;

our ( $opt_h, $opt_V, $opt_s, $opt_R );
getopts("hVs:R");

usage() if $opt_h;
die "$0 version: $version\n" if $opt_V;

my $reload_cache = $opt_R;

# sorts the output of a debtag or apt-cache search by the results 
# from the popularity contest.

my %sortby_best = ( vote => 'highest',
		    inst => 'highest',
		    rank => 'lowest' );

my $sortby = "vote"; # or "inst"

$sortby = $opt_s if $opt_s;

my $debtags = "debtags";
my $aptcache = "apt-cache";
my $popcontest = "http://popcon.debian.org/by_inst.gz";
my $gunzip = "gunzip";
my $localcache = "$ENV{HOME}/.popcon.cache";
my $localcachegz = "$ENV{HOME}/.popcon.cache.gz";

# ############################################################

my @search = @ARGV;

my $ua = LWP::UserAgent->new;

if( ! -f $localcachegz || $reload_cache ){
  print "Downloading popularity contest results...\n";
  $ua->mirror( $popcontest, $localcachegz );
  print "Done.\n";
  print "Decompressing results...\n";
  system( "$gunzip -c $localcachegz > $localcache" );
  print "Done.\n";

}

my %package_rank;

print "Reading package rank cache...\n";
open PKGS, "<", $localcache or die "cannot package rank cache\n";

while ( my $line = <PKGS> ) {
    chomp $line;
    $line =~ s/\#.+$//;
    next if not $line;
  if ( $line =~ /^(\d+)\s+([^\s]+)\s+(\d+)\s+(\d+)\s+/i ) {
      $package_rank{$2}{rank} = $1;
      $package_rank{$2}{inst} = $3;
      $package_rank{$2}{vote} = $4;
  }
}

close PKGS;
print "Done.\n";

my %search_results;

print "Searching...\n";

if( $search[0] =~ /::/ ){
  open(DEBTAGS, "-|", $debtags, "search", @search )
    or die "cannot execute debtags: $!\n";

  while( my $line = <DEBTAGS> ){
    if( $line =~ /^([^\s]+)\s+\-\s+(.+)$/ ){
      $search_results{$1} = $2;
    }
  }
  close DEBTAGS;

}else{
  open (APTCACHE, "-|", $aptcache, "search", @search )
    or die "cannot execute aptcache: $!\n";

  while( my $line = <APTCACHE> ){
    if( $line =~ /^([^\s]+)\s+\-\s+(.+)$/ ){
      $search_results{$1} = $2;
    }
  }
  close APTCACHE;

}


my @results;
if( $sortby_best{$sortby} eq 'lowest' ){
    @results = sort { $package_rank{$a}{$sortby} <=>
			     $package_rank{$b}{$sortby} }
    keys %search_results;

}elsif( $sortby_best{$sortby} eq 'highest' ){
    @results = sort { $package_rank{$b}{$sortby} <=>
			     $package_rank{$a}{$sortby} }
    keys %search_results;

}else{
    die "Unknown sorting order: '". $sortby_best{$sortby}."'\n";
}


foreach my $result (@results){
  print $package_rank{$result}{$sortby}, "\t", 
    $result, " -  ", $search_results{$result}, "\n";
}

exit 0;


sub usage(){
    die <<USAGE;
usage: $0 [options] SEARCH [SEARCH [...]]

Searches the Debian package archive and displays the results
based on popularity. 

SEARCH is a search string for either 'apt-cache search' or
'debtags search'. If SEARCH has '::' in it, it is assumed to be
a debtags search.

options:
    -h          this help
    -V          print version information

Popularity is based on the Debian popularity contest 
<http://popcon.debian.org/>, the results of which are downloaded 
to $localcachegz and sorted by 
Copyright(C) 2006 Steve Pomeroy <steve\@staticfree.info>
Licensed under the GNU GPL. See documentation for complete details.
USAGE

}
