#!/usr/bin/perl -w
#
# Update the ANNOUNCE file for a new release.
#
# Usage: make_announce [new_version]
#
# Copyright 2016 Alexandre Julliard
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#

use strict;
use locale;
use POSIX;
use Text::CSV::Encoded;
binmode STDOUT, ':utf8';

sub unescape($)
{
    my $str = shift;
    $str =~ s/&quot;/\"/g;
    $str =~ s/&apos;/\'/g;
    $str =~ s/&amp;/&/g;
    $str =~ s/&lt;/</g;
    $str =~ s/&gt;/>/g;
    $str =~ s/&#64;/\@/g;
    return $str;
}

# update a file if changed
sub update_file($)
{
    my $file = shift;
    if (!(-f $file) || system "cmp $file $file.new >/dev/null")
    {
        rename "$file.new", "$file";
        print "$file updated\n";
    }
    else
    {
        unlink "$file.new";
    }
}

# determine the current version number
sub get_current_version()
{
    my $version;

    open VERSION, "<VERSION" or die "cannot open VERSION";
    if (<VERSION> =~ /Wine version (\S+)/) { $version = $1; }
    close VERSION;
    die "failed to parse VERSION" unless $version;
    return $version;
}

# retrieve a list of bugs with the specified filter
sub get_bugs($)
{
    my $filter = shift;
    my $csv = Text::CSV::Encoded->new({ encoding_in => "utf-8", encoding_out => "utf-8" });
    my %bugs;

    open QUERY, "-|" or exec "wget", "-qO-", "https://bugs.winehq.org/buglist.cgi?columnlist=short_desc&query_format=advanced&ctype=csv&$filter"
        or die "cannot query bug list";
    <QUERY>;  # skip header line
    while (<QUERY>)
    {
        next unless $csv->parse($_);
        my ($id, $descr) = $csv->fields();
        $bugs{$id} = $descr;
    }
    close QUERY;
    return %bugs;
}

# retrieve the current list of authors
sub get_authors()
{
    my %authors;

    open AUTHORS, "<AUTHORS" or die "cannot open AUTHORS";
    <AUTHORS>;  # skip header line
    while (<AUTHORS>)
    {
        chomp;
        next if /^$/;
        $authors{$_} = 1;
    }
    close AUTHORS;
    return %authors;
}

# determine the version number

my $old = get_current_version();
my $new = $ARGV[0];
unless ($new)
{
    if ($old =~ /^([0-9]+)\.([0-9]+)$/) { $new = "$1.$2.1"; }
    elsif ($old =~ /^([0-9]+)\.([0-9]+)\.([0-9]+)$/) { $new = "$1.$2." . ($3 + 1); }
    elsif ($old =~ /^([0-9]+)\.([0-9]+)-rc([0-9]+)$/) { $new = "$1.$2-rc" . ($3 + 1); }
    else { die "unknown version format $old"; }
}

print "Updating files for release $new\n";

(my $reldir = $new) =~ s/^([0-9]+\.[0-9]+).*/$1/;
my $is_stable = ($new =~ /^([0-9]+)\.([0-9]+)\.([0-9]+)$/) && !($2 % 2);  # stable releases have an even minor number
my $filter = "product=Wine&resolution=FIXED&" . ($is_stable ? "target_milestone=$reldir.x" : "bug_status=RESOLVED");

my %bugs = get_bugs( $filter );
my %authors = get_authors();

# update the ANNOUNCE file

open ANNOUNCE, "<ANNOUNCE" or die "cannot open ANNOUNCE";
open NEW, ">ANNOUNCE.new" or die "cannot create ANNOUNCE.new";
while (<ANNOUNCE>)
{
    last if /^------------------/;
    s!http://mirrors.ibiblio.org/wine/source/.*!http://mirrors.ibiblio.org/wine/source/$reldir/wine-$new.tar.bz2!;
    s!http://dl.winehq.org/wine/source/.*!http://dl.winehq.org/wine/source/$reldir/wine-$new.tar.bz2!;
    print NEW $_;
}

print NEW "----------------------------------------------------------------\n\n";
printf NEW "Bugs fixed in %s (total %u):\n\n", $new, scalar( keys %bugs );
foreach my $id (sort {$a <=> $b} keys %bugs)
{
    printf NEW " %6d  %s\n", $id, unescape( $bugs{$id} );
}

print NEW "\n----------------------------------------------------------------\n\n";
print NEW "Changes since $old:\n\n";

open LOG, "-|" or exec "git", "shortlog", "wine-$old..HEAD" or die "cannot run git shortlog";
while (<LOG>)
{
    if (/^(\S.*)\s\(\d+\):$/) { $authors{$1} = 1; }
    print NEW $_;
}
close LOG;

while (<ANNOUNCE>) { last if /^--$/; }
print NEW "--\n";
while (<ANNOUNCE>) { print NEW $_; }

close ANNOUNCE;
close NEW;
update_file( "ANNOUNCE" );

# update the AUTHORS file

setlocale( LC_COLLATE, "en_US.UTF-8" );

open AUTHORS, ">AUTHORS.new" or die "cannot create AUTHORS.new";
print AUTHORS "Wine is available thanks to the work of:\n\n", join( "\n", sort keys %authors ), "\n";
close AUTHORS;
update_file( "AUTHORS" );
