#!/usr/bin/perl -w

BEGIN {
  unshift @INC, ($::ENV{'BUILD_DIR'} || '/usr/lib/build');
}

use strict;

use Build;

my ($dist, $rpmdeps, $archs, $configdir, $release, $changelog);

while (@ARGV)  {
  if ($ARGV[0] eq '--dist') {
    shift @ARGV;
    $dist = shift @ARGV;
    next;
  }
  if ($ARGV[0] eq '--archpath') {
    shift @ARGV;
    $archs = shift @ARGV;
    next;
  }
  if ($ARGV[0] eq '--configdir') {
    shift @ARGV;
    $configdir = shift @ARGV;
    next;
  }
  if ($ARGV[0] eq '--release') {
    shift @ARGV;
    $release = shift @ARGV;
    next;
  }
  if ($ARGV[0] eq '--changelog') {
    shift @ARGV;
    $changelog = shift @ARGV;
    next;
  }
  last;
}
die("Usage: substitutedeps --dist <dist> --archpath <archpath> [--configdir <configdir>] <specin> <specout>\n") unless @ARGV == 2;
my $spec = $ARGV[0];
my $newspec = $ARGV[1];

my $cf = Build::read_config_dist($dist, $archs, $configdir);

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

my $xspec = [];
my $d = Build::parse($cf, $spec, $xspec) || {};
my @sdeps = @{$d->{'deps'} || []};
my @neg = map {substr($_, 1)} grep {/^-/} @{$d->{'deps'} || []};
my %neg = map {$_ => 1} @neg;
@sdeps = grep {!$neg{$_}} @sdeps;
@sdeps = Build::do_subst($cf, @sdeps);
@sdeps = grep {!$neg{$_}} @sdeps;
my %sdeps = map {$_ => 1} @sdeps;

open(F, '>', $newspec) || die("$newspec: $!\n");

my $used;
my $inchangelog = 0;
for my $l (@$xspec) {
  $used = 1;
  if (ref($l)) {
    if (!defined($l->[1])) {
      $used = 0;
      $l = $l->[0];
    } else {
      $l = $l->[1];
    }
  }

  if ($inchangelog) {
    $inchangelog = 0 if $l =~ /^\s*%[^%]/;
    next if $inchangelog;
  }
  if ($changelog && ($l =~ /\s*\%changelog\b/)) {
    $inchangelog = 1;
    next;
  }

  if ($release) {
    if ($l =~ /^Release:/i) {
      if (!($l =~ s/<RELEASE\d*>/$release/g)) {
	if ($l =~ /<(?:CI_CNT|B_CNT)>/) {
	  # XXX: should pass ci_cnt/b_cnt instead
	  if ($release =~ /(\d+)\.(\d+)$/) {
	    my ($ci, $b) = ($1, $2);
	    $l =~ s/<CI_CNT>/$ci/;
	    $l =~ s/<B_CNT>/$b/;
	  } elsif ($release =~ /(\d+)$/) {
	    my $b = $1;
	    $l =~ s/<B_CNT>/$b/ unless $l =~ s/<CI_CNT>/$b/;
	  }
	} else {
	  $l =~ s/^(Release:\s*).*/$1$release/i;
	}
      }
    }
  }

  if (!$used || ($l !~ /^(?:Build)?Requires:/i)) {
    print F "$l\n";
    next;
  }

  my $isbuildrequires = 0;
  $isbuildrequires = 1 if $l =~ /^BuildRequires:/i;
  my $r = $l;
  $r =~ s/^[^:]*:\s*//;
  my @deps = $r =~ /([^\s\[,]+)(\s+[<=>]+\s+[^\s\[,]+)?[\s,]*/g;
  my @ndeps = ();
  my $replace = 0;
  my @f2 = Build::do_subst_vers($cf, @deps);
  my %f2 = @f2;
  if ($isbuildrequires) {
    delete $f2{$_} for @neg;
    delete $f2{$_} for grep {/^-/} keys %f2;
  }
  while (@deps) {
    my ($pack, $vers) = splice(@deps, 0, 2);
    $vers = '' unless defined $vers;
    if (($isbuildrequires && $sdeps{$pack}) || exists($f2{$pack})) {
      push @ndeps, "$pack$vers";
      delete $f2{$pack};
    } else {
      $replace = 1;
    }
  }
  if (%f2) {
    while (@f2) {
      my ($pack, $vers) = splice(@f2, 0, 2);
      next unless exists $f2{$pack};
      $vers = '' unless defined $vers;
      push @ndeps, "$pack$vers";
    }
    $replace = 1
  }
  if ($replace) {
    $l =~ /^(.*?:\s*)/;
    print F $1.join(' ', @ndeps)."\n" if @ndeps;
  } else {
    print F "$l\n";
  }
}

if ($changelog) {
  print F "%changelog\n";
  if (open(CF, '<', $changelog)) {
    while(<CF>) {
      print F $_;
    }
    close CF;
  }
}

close(F) || die("close: $!\n");

exit(0);
