#!/usr/bin/perl

use strict;

# configuration file; must be valid Perl
my $conf = "/etc/apf/apf.conf";

my $datadir = ".";
my $debug = 0;

# normally you do not need to change anything below

# rsync options
my $opts = "-Pt";

sub usage
{
  print STDERR
    "Usage:\n" .
    " apf <find|search|list|show> <pattern>\n" .
    "or:\n" .
    " apf update\n";
  exit 1;
}

my @config;
my %index = (); my $arch; my $url;

my $command; my $index; my $pattern;
my $file; my $package; my @pkglist;

unless ( -t STDOUT )
{
  $opts .= "q"; # execute rsync quietly when STDOUT is redirected
}

# Process configuration file
if ( -f "$conf" && -r _ && -s _ )
{
  print STDERR "reading $conf\n" if $debug;
  open CONF, "< $conf";
  chomp (@config = <CONF>);
  close CONF;
  eval (join "\n", @config);
  @config = ();
}

$datadir = "." if $datadir eq "";

$command = shift @ARGV;
unless (scalar $command)
{
  &usage;
}

# update
if ($command =~ /^u/i)
{
  umask 022;
  unless ( -d $datadir )
  {
    print STDERR "$datadir missing, attempting to create\n" if $debug;
    system "mkdir -p '$datadir'";
    unless ( -d $datadir )
    {
      print STDERR "Unable to create missing directory $datadir\n";
      exit 1;
    }
  }
  foreach $arch (keys %index)
  {
    $url = $index{$arch};
    $index = "$datadir/index.$arch";
    print STDERR "Fetching $index from $url\n" if $debug;
    last if system "rsync $opts $url $index";
  }
  exit 0;
}

$pattern = shift @ARGV;
unless (scalar $pattern)
{
  &usage;
}

# find
if ($command =~ /^(f|se)/i)
{
  foreach $arch (keys %index)
  {
    $index = "$datadir/index.$arch";
    open INDEX, "<$index" or next;
    while(<INDEX>)
    {
      chomp;
      ($file, $package) = split /\t/;
      next unless $file =~ /$pattern/;
      # output each package name only once, but match on exact names
      next if grep($package eq $_, @pkglist);
      push @pkglist, $package;
      print "$package\n";
    }
    close INDEX;
  }
}
# list
elsif ($command =~ /^(l|sh)/i)
{
  foreach $arch (keys %index)
  {
    $index = "$datadir/index.$arch";
    open INDEX, "<$index" or next;
    while(<INDEX>)
    {
      chomp;
      ($file, $package) = split /\t/;
      next unless $package =~ /$pattern/;
      print "$package:\t$file\n";
    }
    close INDEX;
  }
}
else # $command is unknown
{
  &usage;
}
