#!/usr/bin/env perl

use strict;
use warnings;

use Cwd;
use Getopt::Long;

my $filere='[\w\.\-\_\/]+';
my $branchre='[\w\-\_]+';

my $usage="usage: $0 <checked out directory>";

$#ARGV == 0 or die $usage;

my $base_darcs = getcwd();
chdir($ARGV[0]);
my $base_cvs = getcwd();

chdir($base_cvs);

# $files{workingname}->{version}=[branch1,branch2,...]
my %files=();

my $curfile;

open(LOG,"cvs log -h 2>/dev/null |");

while(<LOG>) {
  /^=====/ and $curfile=undef;
  /^Working file: ($filere)$/ and $curfile=$1;
  if(/^\t($branchre): ([\d\.]+)\.0\.(\d)$/ && ($3 % 2)==0) {
    push @{$files{$curfile}->{$2}},$1;
  }
  # vendor branches - do they always start at 1.1?
  if(/^\t($branchre): 1.1.(\d)$/ && ($2 % 2)==1) {
    push @{$files{$curfile}->{'1.1'}},$1;
  }
}
close LOG;
 
open(LIST,"cvsps -q |");

my $patchset;
my $branch;

sub min {
  my $min;
  foreach my $val (@_) {
    if(!defined $min || (defined $val && $val<$min)) {
      $min=$val;
    }
  }
  return $min;
}

sub max {
  my $max;
  foreach my $val (@_) {
    if(!defined $max || (defined $val && $val>$max)) {
      $max=$val;
    }
  }
  return $max;
}

my %branches=();

# $maxneed{branch}=n
my %maxneed;
my %minavoid;

# $branch{$patchset}=branchname
my %branch;

while(<LIST>) {
  if(/^---------------------/) {
    $patchset=undef;
    $branch=undef;
  }
  if(/^PatchSet (\d+)/) {
    $patchset=$1;
  }
  if(/^Branch: ([\w\-\_]+)/) {
    $branch=$1;
    $branch{$patchset}=$1;
    $branches{$branch}=1;
  }
  # BUG: will get confused by weird stuff in the changelog
  if(my ($name,$from,$to)=/^\t([\w\.\-\_\/]+):([\d\.]+)->([\d\.]+)/) {
    foreach my $branch (@{$files{$name}->{$to}}) {
      $maxneed{$branch}=&max($maxneed{$branch},$patchset);
    }
    foreach my $branch (@{$files{$name}->{$from}}) {
      $minavoid{$branch}=&min($minavoid{$branch},$patchset);
    }
  }
}

close LIST;

foreach my $branch (keys %branches) {
  my $maxneed=$maxneed{$branch};
  my $minavoid=$minavoid{$branch};
  print "$branch: ";
  print $maxneed.' ('.$branch{$maxneed}.')' if defined $maxneed;
  print " INVALID - $minavoid"
    if defined $maxneed && defined $minavoid && $minavoid<=$maxneed;
  print "\n";
}

