#! /usr/bin/perl
#
# update_spec.pl -- merge an attribute file into a spec-file.
#
# (C) 2010 coolo@suse.de, jw@suse.de, Novell Inc.
# Distribute under GPLv2 or GPLv3
#
# -----------------------------------------------------------
# 2010-07-14, jw v1.01 - added support for obsoletes/provides

use Data::Dumper;
my $version = '1.01';

my %multi = map { $_ => 1 } qw(provides obsoletes);

die qq{update_spec.pl V$version
Usage:
 $0 specfile attributes > specfile.new;
 mv specfile.new specfile
} unless @ARGV;

my $name = $ARGV[0];	# specfile
$name =~ s,.*/,,;	# remove path prefix
$name =~ s,\.spec.*,,;	# remove .spec suffix

my %attributes = ();
open(FILE, "<", $ARGV[1]) || die 'no attributes';
my $pack = undef;
my $text = undef;
while ( <FILE> ) {
	if (/^\+(.*)$/) { $pack = $1; $text = ''; next }
	if (/^-(.*)$/) {
	    if ($pack ne $1) {
		die "$pack and $1 do not match";
	    }
	    store_attr($pack, $text);
	    $text = undef;
	    $pack = undef;
	    next;
	}
	if (defined $text) {
	    $text .= $_;
	} elsif (/^(\S*)\s*(.*)$/) {
	    store_attr($1, $2);
	}
}
close(FILE);

sub store_attr
{
  my ($key, $value) = @_;
  my $tag = $1 if $key =~ m{^(\w+)(\..*)$};

  $value =~ s,^\s*,,;	# remove whitespace front
  $value =~ s,\s*$,,;	# ... and back

  if ($multi{$tag||''})
    {
      push @{$attributes{$key}}, $value;
    }
  else
    {
      die "multiple key $key = $value',\n was $key = '$attributes{$key}'\n"
        if exists $attributes{$key};
      $attributes{$key} = $value;
    }
}

sub flush_multi
{
  my ($pname, @key) = @_;

  @key = keys %multi unless @key;
  for my $k (@key)
    {
      my $k_dot_p = (lc $k) .'.'. $pname;
      for my $v (@{$attributes{$k_dot_p}})
        {
	  printf "%s: %s\n",  ucfirst $k, $v;
	}
      delete $attributes{$k_dot_p};
    }
  print "\n" unless $_[1];
}

open(FILE, "<", $ARGV[0]) or die "cannot open $ARGV[0]: $!\n";

sub description()
{
  if (/^%description\s*(.*)\s*/) {
  	flush_multi($pname||$name);	# last chance: directly before description

        my $suffix = $1;
        my $pname = $name;

       if ($suffix =~ m/-n\s*(.*)/) {
               $pname = $1;
        } else {
               $pname = "$name-$suffix" if ($suffix);
       }

        if (defined $attributes{"description.$pname"}) {
           print $_;
           my $descr = $attributes{"description.$pname"};
           print "$descr\n";
           $_ = '';
           do {
	       $_ = <FILE>;
           } while ( $_ !~ /^%/ && $_ !~ /^@/ );
           print "\n";
           description();
        }
  }

}

# current subpackage
my $pname = $name;

while ( <FILE> )
{
  if (/^Name:\s*(.*)/) {
	$name = $1;
	$pname = $1;
  }
  description();

  if (/^%package\s*(.*)/) {
      my $suffix = $1;
      if ($suffix =~ m/-n\s*(.*)/) {
	  $pname = $1;
      } else {
	  $pname = "$name-$1";
      }
  }

  if (/^(Summary:\s*)(.*)$/) {
      if (defined $attributes{"summary.$pname"}) {
	  print $1 . $attributes{"summary.$pname"} ."\n";
	  next;
      }
  }
  if (/^(License:\s*)(.*)$/) {
      if (defined $attributes{"license.$pname"}) {
	  print $1 . $attributes{"license.$pname"} ."\n";
	  next;
      }
  }
  if (/^(Group:\s*)(.*)$/) {
      if (defined $attributes{"group.$pname"}) {
	  print $1 . $attributes{"group.$pname"} ."\n";
	  next;
      }
  }

  # FIXME: the above and below lists of tags should be dynamic, no?

  if (/^(Obsoletes:\s*)(.*)$/) {
  	flush_multi($pname, 'obsoletes');
  }
  if (/^(Provides:\s*)(.*)$/) {
  	flush_multi($pname, 'provides');
  }
  print $_;
}

close(FILE);
