#!/usr/bin/perl
#**************************************************************
#  
#  Licensed to the Apache Software Foundation (ASF) under one
#  or more contributor license agreements.  See the NOTICE file
#  distributed with this work for additional information
#  regarding copyright ownership.  The ASF licenses this file
#  to you under the Apache License, Version 2.0 (the
#  "License"); you may not use this file except in compliance
#  with the License.  You may obtain a copy of the License at
#  
#    http://www.apache.org/licenses/LICENSE-2.0
#  
#  Unless required by applicable law or agreed to in writing,
#  software distributed under the License is distributed on an
#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#  KIND, either express or implied.  See the License for the
#  specific language governing permissions and limitations
#  under the License.
#  
#**************************************************************

use strict;
use warnings;
use XML::LibXML;
use open OUT => ":utf8";
use LWP::Simple;
use Digest;
use Digest::MD5;
use Digest::SHA;
use File::Temp;
use File::Path;

use Carp::always;

=head1 NAME

    build_release.pl - Tool for batch release builds and uploads and the creation of wiki pages that list install sets.

=head1 SYNOPSIS

    build_release.pl <command> {option} <release-description.xml>
    
    comands:
        build      builds all install sets as requested by the XML file and supported by the platform.
        build-missing
                   build only those install sets that have not been built earlier.
        upload     upload install sets to a local or remote (via ssh with public/private key)
                   directory structure.  Uploads install sets that where build on other platforms.
        wiki       create a wiki (MediaWiki syntax) snippet that references all install sets at the upload
                   location.  Includes install sets that where built and/or uploaded from other
                   platforms and machines.
    options:
        -j <count>    maximum number of build processes
        -k            keep going if there are recoverable errors
        -u <path>     upload destination
        -l            check links on wiki page, write broken links as plain text
        -ld           check links on wiki page, mark broken links
        -o <filename> filename of the output (wiki: wiki page, build: makefile)
        -n <number>   maximal number of upload tries, defaults to 5.
        -d            dry-run

    Typical calls are:
       build_release.pl build -j4 instsetoo_native/util/aoo-410-release.xml
           for building the installation sets, language packs and patches for the 4.1 release.
    
       build_release.pl upload -u me@server:path -n 3 instsetoo_native/util/aoo-410-release.xml
           to upload the previously built installation sets etc.

       build_release.pl wiki -o /tmp/wiki.txt instsetoo_native/util/aoo-410-release.xml
           to create an updated wiki page with installation sets etc built at several
           places and uploaded to several locations.

    
=head1 XML file format

The release description could look like this:

<release 
    name="snapshot"
    version="4.1.0">

    <language
        id="ast"                            # As specified by 'configure --with-lang'
        english-name="Asturian"
        local-name="Asturianu"
        />
    ... more languages
    
    <platform
        id="wntmsci12.pro"
        display-name="Windows"
        archive-platform="Win_x86"
        word-size="32"
        package-types="msi"
        extension="exe"
        />
    ... more platforms

    <download
        platform-id="wntmsci12.pro"
        base-url="http://people.apache.org/~somebody/developer-snapshots/snapshot/win32"
        />

    <package
        id="openoffice"
        target="openoffice"
        display-name="Full Install"
        archive-name="Apache_OpenOffice_%V_%P_install%T_%L.%E"
        />

    <build
        package-id="openoffice"
        platform-list="all"
        language-list="all"
        />
    ... more build entries

  <wiki>
    <package-ref
        package-id="openoffice"
        language-list="all"
        platform-list="all"
        table="main"
        />
    ... more packages
  </wiki>
   
</release>

A single <release> tag contains any number of

<language>  id
                The language id used internally by the build process, eg de, en-US
            english-name
                The english name of the language, eg german
            local-name 
                The language name in that language, eg Deutsch

    Each listed language is expected to have been passed to configure via --with-lang
    The set of languages defines for which languages to
          build installation sets, language packs etc. (build command) 
          upload installation sets, etc (upload command)
          add rows in the wiki page (wiki command)

<platform>  id
                The platform id that is used internally by the build process, eg wntmsci12.pro
                Note that <p>.pro and <p> are treated as two different platforms.
            display-name
                Name which is printed in the wiki table.
            archive-platform
                Platform name as used in the name of the installation set, eg Win_x86
            word-size
                Bit size of the installation sets, etc, typically either 32 or 64
            package-types
                Semicolon separated list of package types, eg "msi" or "deb;rpm"
            add-package-type-to-archive-name
                For deb and rpm archives it is necessary to add the package type to the archive name.
            extension
                Extension of the archive name, eg "exe" or "tar.gz"

    For the build command only those <platform> elements are used that match the platform on which this
    script is run.

<download>
            platform-id
                Reference to one of the <platform> elements and has to match the id attribute of that platform.
            base-url
                URL head to which the name of the downloadable installation set etc. is appended.
                Eg. http://people.apache.org/~somebody/developer-snapshots/snapshot/win32

    Defines one download source that is referenced in the wiki page.  Multiple <download> elements
    per platform are possible.  Earlier entires are preferred over later ones.

<package>
            id
                Internal name that is used to reference the package.
            target
                Target name recognized by instsetoo_native/util/makefile.mk, eg openoffice or oolanguagepack.
            display-name
                Name of the package that is shown in the wiki page, eg "Full Install" or "Langpack".
            archive-name
                Template of the archive name.
                %V version
                %P archive package name
                %T package type
                %L language
                %E extension.

    Defines a downloadable and distributable package, eg openoffice for the binary OpenOffice installation set.
    
<build>     target
            platform-list
                Semicolon separated list of platforms for which to build the target.
                Ignores all platforms that don't match the  platform on which this script is executed.
                The special value 'all' is a shortcut for all platforms listed by <platform> elements.
            language-list
                Semicolon separated list of languages for which the build the target.
                The special value 'all' is a shortcut for all languages listed by <language> elements.

    Defines the sets of targets, plaforms and languages which are to be built.

<wiki>
    <package-ref>
            package-id
                The id of the referenced package.
            platform-list
                See <build> tag for explanation.
            language-list
                See <build> tag for explanation.
            table
                Specifies the wiki table into which to add the package lines.  Can be "main" or "secondary".
                
=cut
    


my %EnUSBasedLanguages = (
    'ast' => 1
    );


sub ProcessCommandline (@);
sub PrintUsageAndExit ();
sub Trim ($);
sub ReadReleaseDescription ($$);
sub ProcessBuildDescription ($$$);
sub ProcessPlatformDescription ($$);
sub ProcessDownloadDescription ($$);
sub ProcessPackageDescription ($$);
sub ProcessWikiPackageDescription ($$$);
sub ProcessLanguageDescription ($$);
sub PostprocessLanguageList ($$);
sub PostprocessPlatformList ($$);
sub CheckLanguageSet ($@);
sub WriteMakefile ($$);
sub Upload ($$);
sub PrepareUploadArea ($@);
sub UploadFilesViaRsync ($$@);
sub CollectDownloadSets ($);
sub ProvideChecksums ($@);
sub IsOlderThan ($$);
sub GetInstallationPackageName ($$$$);
sub ResolveTemplate ($$$$$);
sub GetCurrentPlatformDescriptor ($);
sub Wiki ($$);
sub GetTableList ($);
sub GetPackagesForTable ($$);
sub GetLanguagesForTable ($@);
sub GetPlatformsForTable ($@);
sub WriteDownloadLinks ($$$$$$$);
sub FindDownload ($$$$$);
sub CreateLink ($$$);
sub CheckLink ($);
sub SignFile ($$);

sub ProcessCommandline (@)
{
    my @arguments = @_;

    my $command = undef;
    my $description_filename = undef;
    my $max_process_count = 1;
    my $keep_going = 0;
    my $upload_destination = undef;
    my $check_links = 0;
    my $mark_broken_links = 0;
    my $output_filename = undef;
    my $max_upload_count = 5;
    my $build_only_missing = 0;
    my $dry_run = 0;

    my $error = 0;
    while (scalar @arguments > 0)
    {
        my $argument = shift @arguments;
        if ($argument =~ /^-/)
        {
            if ($argument eq "-j")
            {
                $max_process_count = shift @arguments;
            }
            elsif ($argument eq "-u")
            {
                $upload_destination = shift @arguments;
                $upload_destination =~ s/(\\|\/)$//;
            }
            elsif ($argument eq "-k")
            {
                $keep_going = 1;
            }
            elsif ($argument eq "-l")
            {
                $check_links = 1;
            }
            elsif ($argument eq "-ld")
            {
                $check_links = 1;
                $mark_broken_links = 1;
            }
            elsif ($argument eq "-o")
            {
                $output_filename = shift @arguments;
            }
            elsif ($argument eq "-n")
            {
                $max_upload_count = shift @arguments;
            }
            elsif ($argument eq "-d")
            {
                $dry_run = 1;
            }
            else
            {
                printf STDERR "unknown option $argument %s\n", $argument;
                $error = 1;
            }
        }
        elsif ( ! defined $command)
        {
            $command = $argument;
            if ($command eq "build-missing")
            {
                $command = "build";
                $build_only_missing = 1;
            }
            elsif ($command !~ /^(build|build-missing|upload|wiki)$/)
            {
                printf STDERR "unknown command '%s'\n", $command;
                $error = 1;
            }
        }
        else
        {
            $description_filename = $argument;
            if ( ! -f $description_filename)
            {
                print STDERR "can not open release description '%s'\n", $description_filename;
                $error = 1;
            }
        }
    }

    if ( ! defined $description_filename)
    {
        $error = 1;
    }
    if (! defined $command)
    {
        printf STDERR "ERROR: no command\n";
        $error = 1;
    }
    elsif ($command =~ /^(wiki)$/)
    {
        if ( ! defined $output_filename)
        {
            printf STDERR "ERROR: no output filename\n",
            $error = 1;
        }
    }
    
    if ($error)
    {
        PrintUsageAndExit();
    }

    return {
        'command' => $command,
        'filename' => $description_filename,
        'max-process-count' => $max_process_count,
        'keep-going' => $keep_going,
        'upload-destination' => $upload_destination,
        'check-links' => $check_links,
        'mark-broken-links' => $mark_broken_links,
        'output-filename' => $output_filename,
        'max-upload-count' => $max_upload_count,
        'build-only-missing' => $build_only_missing,
        'dry-run' => $dry_run
    };
}




sub PrintUsageAndExit ()
{
    print STDERR "usage: $0 <command> {option} <release-description.xml>\n";
    print STDERR "    comands:\n";
    print STDERR "        build\n";
    print STDERR "        build-missing\n";
    print STDERR "        upload\n";
    print STDERR "        wiki     create a download page in MediaWiki syntax\n";
    print STDERR "    options:\n";
    print STDERR "    -j <count>    maximum number of build processes\n";
    print STDERR "    -k            keep going if there are recoverable errors\n";
    print STDERR "    -u <path>     upload destination\n";
    print STDERR "    -l            check links on wiki page, write broken links as plain text\n";
    print STDERR "    -ld           check links on wiki page, mark broken links\n";
    print STDERR "    -o <filename> filename of the output (wiki: wiki page, build: makefile)\n";
    print STDERR "    -n <number>   maximal number of upload tries, defaults to 5.\n";
    print STDERR "    -d            dry run\n";
    exit(1);
}




=head2 Trim ($text)

    Remove leading and trailing space from the given string.

=cut
sub Trim ($)
{
    my ($text) = @_;
    $text =~ s/^\s+|\s+$//g;
    return $text;
}




=head2 ReadReleaseDescription ($$)

    Read the release description from $filename.
    
=cut
sub ReadReleaseDescription ($$)
{
    my ($filename, $context) = @_;

    my $document = XML::LibXML->load_xml('location' => $filename);
    my $root = $document->documentElement();

    # Initialize the release description.
    my $release = {
        'name' => $root->getAttribute("name"),
        'version' => $root->getAttribute("version"),
        'previous-version' => $root->getAttribute("previous-version"),
        'builds' => [],
        'languages' => {},
        'language-ids' => [],
        'platforms' => {},
        'downloads' => [],
        'packages' => {},
        'platform-ids' => [],
        'wiki-packages' => []
    };
    
    # Process the language descriptions.
    for my $language_element ($root->getChildrenByTagName("language"))
    {
        my $language_descriptor = ProcessLanguageDescription($language_element, $context);
        $release->{'languages'}->{$language_descriptor->{'id'}} = $language_descriptor;
        push @{$release->{'language-ids'}}, $language_descriptor->{'id'};
    }
    printf "%d languages\n", scalar keys %{$release->{'languages'}};

    # Process the platform descriptions.
    for my $platform_element ($root->getChildrenByTagName("platform"))
    {
        my $platform_descriptor = ProcessPlatformDescription($platform_element, $context);
        $release->{'platforms'}->{$platform_descriptor->{'id'}} = $platform_descriptor;
        push @{$release->{'platform-ids'}}, $platform_descriptor->{'id'};
    }
    printf "%d platforms\n", scalar keys %{$release->{'platforms'}};

    # Process the package descriptions.
    for my $package_element ($root->getChildrenByTagName("package"))
    {
        my $package_descriptor = ProcessPackageDescription($package_element, $context);
        $release->{'packages'}->{$package_descriptor->{'id'}} = $package_descriptor;
    }
    printf "%d packages\n", scalar keys %{$release->{'packages'}};

    # Platform specific the package descriptions.
    for my $package_element ($root->getChildrenByTagName("platform-package"))
    {
        my $package_descriptor = ProcessPlatformPackageDescription($package_element, $context);
        my $key = $package_descriptor->{'platform-id'} . "/" . $package_descriptor->{'package-id'};
        $release->{'platform-packages'}->{$key} = $package_descriptor;
    }
    printf "%d platform packages\n", scalar keys %{$release->{'platform-packages'}};

    # Process the download descriptions.
    for my $download_element ($root->getChildrenByTagName("download"))
    {
        my $download_descriptor = ProcessDownloadDescription($download_element, $context);
        push @{$release->{'downloads'}}, $download_descriptor;
    }
    printf "%d downloads\n", scalar @{$release->{'downloads'}};

    if ($context->{'command'} =~ /^(build|upload)$/)
    {
        # Process the build descriptions.
        for my $build_element ($root->getChildrenByTagName("build"))
        {
            push @{$release->{'builds'}}, ProcessBuildDescription($build_element, $context, $release);
        }
        printf "%d build targets\n", scalar @{$release->{'builds'}};
    }    

    if ($context->{'command'} eq "wiki")
    {
        for my $wiki_element ($root->getChildrenByTagName("wiki"))
        {
            for my $wiki_package_element ($wiki_element->getChildrenByTagName("package-ref"))
            {
                my $wiki_package = ProcessWikiPackageDescription(
                    $wiki_package_element,
                    $context,
                    $release);
                push @{$release->{'wiki-packages'}}, $wiki_package;
            }
        }
        printf "%d wiki packages\n", scalar @{$release->{'wiki-packages'}};
    }

    return $release;
}




=head ProcessBuildDescription ($build_element, $context, $release_descriptor)

    Process one <build> element.

    If its platform-list does not match the current platform then the <build> element is ignored.

=cut
sub ProcessBuildDescription ($$$)
{
    my ($build_element, $context, $release_descriptor) = @_;

    my $package_id = $build_element->getAttribute("package-id");
    my $languages = PostprocessLanguageList($build_element->getAttribute("language-list"), $release_descriptor);
    my $platforms = PostprocessPlatformList($build_element->getAttribute("platform-list"), $release_descriptor);

    # Check if the platform matches any for which the product shall be built.
    my $current_platform = $ENV{'INPATH'};
    my $is_platform_match = 0;
    foreach my $platform_id (@$platforms)
    {
        if ($platform_id eq $current_platform)
        {
            $is_platform_match=1;
            last;
        }
    }
    if ($is_platform_match)
    {
        printf "including build %s\n", $package_id;
    }
    else
    {
        printf "skipping build %s: no platform match\n", $package_id;
        printf "none of the platforms %s matches %s\n",
        join(", ", keys %{$release_descriptor->{'platforms'}}),
        $current_platform;
        return;
    }

    my @languages = CheckLanguageSet($context, @$languages);
    
    return {
        'package-id' => $package_id,
        'platform-list' => $platforms,
        'language-list' => \@languages
    };
}





=head2 ProcessPlatformDescription ($element, $context)

    Process one <platform> element.

    The corresponding platform descriptor is returned as a hash.
    
=cut
sub ProcessPlatformDescription ($$)
{
    my ($element, $context) = @_;

    my $descriptor = {};
    # Mandatory tags.
    foreach my $id ("id", "display-name", "archive-platform", "word-size", "package-types")
    {
        $descriptor->{$id} = $element->getAttribute($id);
        die "release/platform has no attribute $id" unless defined $descriptor->{$id};
    }
    # Optional tags.
    foreach my $id ("extension", "add-package-type-to-archive-name")
    {
        my $value = $element->getAttribute($id);
        $descriptor->{$id} = $value if defined $value;
    }

    $descriptor->{'add-package-type-to-archive-name'} = 0
        unless defined $descriptor->{'add-package-type-to-archive-name'};
    $descriptor->{'package-types'} = [split(/;/, $descriptor->{'package-types'})];

    return $descriptor;
}




=head2 ProcessDownloadDescription ($element, $context)

    Process one <download> element.

    The corresponding download descriptor is returned as a hash.
    
=cut
sub ProcessDownloadDescription ($$)
{
    my ($element, $context) = @_;

    my $descriptor = {};
    
    # Mandatory tags.
    foreach my $id ("platform-id", "base-url")
    {
        $descriptor->{$id} = $element->getAttribute($id);
        die "release/download has no attribute $id" unless defined $descriptor->{$id};
    }

    return $descriptor;
}




=head2 ProcessPackageDescription ($element, $context)

    Process one <package> element.

    The corresponding package descriptor is returned as a hash.
    
=cut
sub ProcessPackageDescription ($$)
{
    my ($element, $context) = @_;

    my $descriptor = {};
    
    # Mandatory tags.
    foreach my $id ("id", "target", "archive-path", "archive-name", "display-name")
    {
        $descriptor->{$id} = $element->getAttribute($id);
        die "release/package has no attribute $id" unless defined $descriptor->{$id};
        die "release/package attribute $id is empty" unless $descriptor->{$id} !~ /^\s*$/;
    }
    # Optional tags.
    foreach my $id ("link-tooltip", "link-URL", "download-extension")
    {
        my $value = $element->getAttribute($id);
        $descriptor->{$id} = $value if defined $value;
    }

    return $descriptor;
}




=head2 ProcessPlatformPackageDescription ($element, $context)

    Process one <platform-package> element.

    The corresponding package descriptor is returned as a hash.
    
=cut
sub ProcessPlatformPackageDescription ($$)
{
    my ($element, $context) = @_;

    my $descriptor = {};
    
    # Mandatory tags.
    foreach my $id ("platform-id", "package-id")
    {
        $descriptor->{$id} = $element->getAttribute($id);
        die "release/package has no attribute $id" unless defined $descriptor->{$id};
        die "release/package attribute $id is empty" unless $descriptor->{$id} !~ /^\s*$/;
    }
    # Optional tags.
    foreach my $id ("extension", "package-types")
    {
        my $value = $element->getAttribute($id);
        $descriptor->{$id} = $value if defined $value;
    }
    if (defined $descriptor->{'package-types'})
    {
        $descriptor->{'package-types'} = [split(/;/, $descriptor->{'package-types'})];
    }

    return $descriptor;
}




=head2 ProcessWikiPackageDescription ($element, $context)

    Process one <wiki><package-ref> element.

    The corresponding descriptor is returned as a hash.
    
=cut
sub ProcessWikiPackageDescription ($$$)
{
    my ($element, $context, $release_descriptor) = @_;

    my $descriptor = {};
    # Mandatory tags.
    foreach my $id ("package-id", "table")
    {
        $descriptor->{$id} = $element->getAttribute($id);
        die "wiki/package-ref has no attribute $id" unless defined $descriptor->{$id};
        die "wiki/package-ref attribute $id is empty" unless $descriptor->{$id} !~ /^\s*$/;
    }

    $descriptor->{'language-list'} = PostprocessLanguageList(
        $element->getAttribute("language-list"),
        $release_descriptor);
    $descriptor->{'platform-list'} = PostprocessPlatformList(
        $element->getAttribute("platform-list"),
        $release_descriptor);

    $descriptor->{'languages'} = {map{$_=>1} @{$descriptor->{'language-list'}}};
    $descriptor->{'platforms'} = {map{$_=>1} @{$descriptor->{'platform-list'}}};

    return $descriptor;
}




=head2 ProcessLanguageDescription ($element, $context)

    Process one <language> element.

    The corresponding language descriptor is returned as a hash.
    
=cut
sub ProcessLanguageDescription ($$)
{
    my ($element, $context) = @_;

    my $descriptor = {};
    foreach my $id ("id", "english-name", "local-name")
    {
        $descriptor->{$id} = $element->getAttribute($id);
        die "wiki/language has no attribute $id" unless defined $descriptor->{$id};
    }

    return $descriptor;
}




=head2 PostprocessLanguageList ($language_list, $release_descriptor)

    Process a language list that is given as 'language-list' attribute to some tags.

    If the attribute is missing, ie $language_list is undef, or its value is "all",
    then the returned list of languages is set to all languages defined via <language> elements.
    
=cut
sub PostprocessLanguageList ($$)
{
    my ($language_list, $release_descriptor) = @_;

    my @matching_languages = ();
    if ( ! defined $language_list
        || $language_list eq "all")
    {
        @matching_languages = sort keys %{$release_descriptor->{'languages'}};
    }
    else
    {
        @matching_languages = split(/;/, $language_list);
    }

    return \@matching_languages;
}




=head2 PostprocessPlatformList ($platform_list, $release_descriptor)

    Process a platform list that is given as 'platform-list' attribute to some tags.

    If the attribute is missing, ie $platform_list is undef, or its value is "all",
    then the returned list of platforms is set to all platforms defined via <platform> elements.
    
=cut
sub PostprocessPlatformList ($$)
{
    my ($platform_list, $release_descriptor) = @_;

    my @matching_platforms = ();
    if ( ! defined $platform_list
        || $platform_list eq "all")
    {
        @matching_platforms = sort keys %{$release_descriptor->{'platforms'}};
    }
    else
    {
        @matching_platforms = split(/;/, $platform_list);
    }
    
    return \@matching_platforms;
}




=head2 CheckLanguageSet ($context, @languages)

    Compare the given list of languages with the one defined by the 'WITH_LANG' environment variable.

    This is to ensure that configure --with-lang was called with the same set of languages that are
    listed by the <language> elements.
    
=cut
sub CheckLanguageSet ($@)
{
    my ($context, @languages) = @_;
    my %configured_languages = map{$_=>1} split(/\s+/, $ENV{'WITH_LANG'});

    my @missing_languages = ();
    my @present_languages = ();
    for my $language (@languages)
    {
        if (defined $configured_languages{$language})
        {
            push @present_languages, $language;
        }
        else
        {
            push @missing_languages, $language;
        }
    }

    if (scalar @missing_languages > 0)
    {
        my $message_head = $context->{'keep-going'} ? "WARNING" : "ERROR";
        printf STDERR "%s: there are languages that where not configured via --with-lang:\n", $message_head;
        printf STDERR "%s:     %s\n", $message_head, join(", ", @missing_languages);
        if ($context->{'keep-going'})
        {
            printf "    available languages:\n";
            printf "        %s\n", join(", ", @present_languages);
        }
        else
        {    
            printf STDERR "ERROR: please rerun configure with --with-lang=\"%s\"\n", join(" ", @languages);
            exit(1);
        }
    }

    return @present_languages;
}




=head2 WriteMakefile ($release_descriptor, $context)

    Write a makefile with all targets that match the <build> elements.

    The use of a makefile allows us to use make to handle concurrent building.

    When an output file was specified on the command line (option -o) then the
    makefile is written to that file but make is not run.

    When no output file was specified then the makefile is written to a temporary
    file.  Then make is run for this makefile.

=cut
sub WriteMakefile ($$)
{
    my ($release_descriptor, $context) = @_;

    my $filename = $context->{'output-filename'};
    if ( ! defined $filename)
    {
        $filename = File::Temp->new();
    }

    # Collect the targets to make.
    my @targets = ();
    foreach my $build (@{$release_descriptor->{'builds'}})
    {
        my $platform_descriptor = GetCurrentPlatformDescriptor($release_descriptor);
        my $package_descriptor = $release_descriptor->{'packages'}->{$build->{'package-id'}};
        my $platform_package_descriptor = GetPlatformPackage(
            $release_descriptor,
            $platform_descriptor,
            $package_descriptor);

        foreach my $language_id (@{$build->{'language-list'}})
        {
            foreach my $package_format (@{$platform_package_descriptor->{'package-types'}})
            {
                my $full_target = sprintf("%s_%s.%s",
                    $package_descriptor->{'target'},
                    $language_id,
                    $package_format);
                if ($context->{'build-only-missing'})
                {
                    my ($archive_path, $archive_name) = GetInstallationPackageName(
                        $release_descriptor,
                        $platform_package_descriptor,
                        $package_format,
                        $language_id);
                    my $candidate = $archive_path . "/" . $archive_name;
                    if (-f $candidate)
                    {
                        printf "download set for %s already exists, skipping\n", $full_target;
                        next;
                    }
                    else
                    {
                        printf "%s  %s\n", $archive_path, $archive_name;
                    }
                }
                push @targets, $full_target;
            }
        }
    }

    # Write the makefile.
    open my $make, ">", $filename;

    # Write dependencies of 'all' on the products in all languages.
    print $make "all .PHONY : \\\n    ";
    printf $make "%s\n", join(" \\\n    ", @targets);
    printf $make "\n\n";

    if ($context->{'dry-run'})
    {
        printf ("adding make fules for\n    %s\n", join("\n    ", @targets));
    }

    # Write rules that chain dmake in instsetoo_native/util.
    foreach my $target (@targets)
    {
        printf $make "%s :\n", $target;
        printf $make "\tdmake \$@ release=t\n";
    }
    close $make;

    
    if ( ! defined $context->{'output-filename'})
    {
        # Caller wants us to run make.
        my $path = $ENV{'SRC_ROOT'} . "/instsetoo_native/util";
        my $command = sprintf("make -f \"%s\" -C \"%s\" -j%d",
            $filename,
            $path,
            $context->{'max-process-count'});
        if ($context->{'dry-run'})
        {
            printf "would run %s\n", $command;
        }
        else
        {
            printf "running %s\n", $command;
            system($command);
        }
    }
}




sub Upload ($$)
{
    my ($release_descriptor, $context) = @_;

    if ( ! defined $context->{'upload-destination'})
    {
        printf STDERR "ERROR: upload destination is missing\n";
        PrintUsageAndExit();
    }

    my @download_sets = CollectDownloadSets($release_descriptor);

    ProvideChecksums($context, @download_sets);
    my $source_path = PrepareUploadArea($context, @download_sets);
    if ( ! defined $source_path)
    {
        exit(1);
    }
    if ( ! UploadFilesViaRsync($context, $source_path, @download_sets))
    {
        exit(1);
    }
}




=head2 PrepareUploadArea ($context, @download_sets)

    Create a temporary directory with the same sub directory strcuture that is requested in the upload location.
    The files that are to be uploaded are not copied but linked into this temporary directory tree.

    Returns the name of the temporary directory.
    
=cut
sub PrepareUploadArea ($@)
{
    my ($context, @download_sets) = @_;
    
    my $tmpdir = File::Temp->newdir();
    foreach my $download_set (@download_sets)
    {
        foreach my $extension ("", ".md5", ".sha256", ".asc")
        {
            my $basename = sprintf("%s%s", $download_set->{'archive-name'}, $extension);
            my $source_path = $download_set->{'source-path'};
            my $source = sprintf("%s/%s", $source_path, $basename);
            my $target_path = sprintf("%s/%s", $tmpdir, $download_set->{'destination-path'});
            my $target = sprintf("%s/%s", $target_path, $basename);
            if ($context->{'dry-run'})
            {
                printf "would create link for %s\n", $basename;
                printf "    %s\n", $source_path;
                printf " to %s\n", $target_path;
            }
            else
            {
                mkpath($target_path);
                unlink $target if ( -f $target);
                my $result = symlink($source, $target);
                if ($result != 1)
                {
                    printf "ERROR: can not created symbolic link to %s\n", $basename;
                    printf "       %s\n", $source;
                    printf "    -> %s\n", $target;
                    return undef;
                }
            }
        }
    }

    return $tmpdir;
}




sub UploadFilesViaRsync ($$@)
{
    my ($context, $source_path, @download_sets) = @_;


    # Collect the rsync flags.
    my @rsync_options = (
        "-L",         # Copy linked files
        "-a",         # Transfer the local attributes and modification times.
        "-c",         # Use checksums to compare source and destination files.
        "--progress", # Show a progress indicator
        "--partial",  # Try to resume a previously failed upload
        );

    # (Optional) Add flags for upload to ssh server 
    my $upload_destination = $context->{'upload-destination'};
    if ($upload_destination =~ /@/)
    {
        push @rsync_options, ("-e", "ssh");
    }

    # Set up the rsync command.
    my $command = sprintf("rsync %s \"%s/\" \"%s\"",
        join(" ", @rsync_options),
        $source_path,
        $upload_destination);
    printf "%s\n", $command;

    if ($context->{'dry-run'})
    {
        printf "would run %s up to %d times\n", $command, $context->{'max-upload-count'};
    }
    else
    {
        # Run the command.  If it fails, repeat a number of times.
        my $max_run_count = $context->{'max-upload-count'};
        for (my $run_index=1; $run_index<=$max_run_count && scalar @download_sets>0; ++$run_index)
        {
            my $result = system($command);
            printf "%d %d\n", $result, $?;
            return 1 if $result == 0;
        }
        printf "ERROR: could not upload all files without error in %d runs\n", $max_run_count;
        return 0;
    }
}




sub CollectDownloadSets ($)
{
    my ($release_descriptor) = @_;

    my @download_sets = ();
    
    foreach my $platform_descriptor (values %{$release_descriptor->{'platforms'}})
    {
        my $platform_path = sprintf("%s/instsetoo_native/%s",
            $ENV{'SOLARSRC'},
            $platform_descriptor->{'id'});
        if ( ! -d $platform_path)
        {
            printf "ignoring missing %s\n", $platform_path;
            next;
        }
        for my $package_descriptor (values %{$release_descriptor->{'packages'}})
        {
            my $platform_package_descriptor = GetPlatformPackage(
                $release_descriptor,
                $platform_descriptor,
                $package_descriptor);
            my @package_formats = @{$platform_descriptor->{'package-types'}};
            for my $package_format (@package_formats)
            {
                for my $language_id (@{$release_descriptor->{'language-ids'}})
                {
                    my ($archive_path, $archive_name) = GetInstallationPackageName(
                        $release_descriptor,
                        $platform_package_descriptor,
                        $package_format,
                        $language_id);
                    my $candidate = $archive_path."/".$archive_name;
                    if ( ! -f $candidate)
                    {
#                        printf STDERR "ERROR: can not find download set '%s'\n", $candidate;
                        next;
                    }
                    printf "adding %s\n", $archive_name;
                    my $download_set = {
                        'source-path' => $archive_path,
                        'archive-name' => $archive_name,
                        'platform' => $platform_descriptor->{'archive-platform'},
                        'destination-path' => sprintf("developer-snapshots/%s/%s",
                            $release_descriptor->{'name'},
                            $platform_descriptor->{'archive-platform'})
                    };
                    printf "    %s\n", $download_set->{'destination-path'};
                    push @download_sets, $download_set;
                }
            }
        }
    }

    return @download_sets;
}




=head2 ProvideChecksums ($context, @download_sets)

    Create checksums in MD5 and SHA256 format and a gpg signature for the given download set.
    The checksums are not created when they already exists and are not older than the download set.
    
=cut
sub ProvideChecksums ($@)
{
    my ($context, @download_sets) = @_;

    my @asc_requests = ();
    foreach my $download_set (@download_sets)
    {
        printf "%s\n", $download_set->{'archive-name'};
        my $full_archive_name = $download_set->{'source-path'} . "/" . $download_set->{'archive-name'};
        $full_archive_name = Trim(qx(cygpath -u "$full_archive_name"));

        my $md5_filename = $full_archive_name . ".md5";
        if ( ! -f $md5_filename || IsOlderThan($md5_filename, $full_archive_name))
        {
            if ($context->{'dry-run'})
            {
                printf "    would create MD5\n";
            }
            else
            {
                my $digest = Digest::MD5->new();
                open my ($in), $full_archive_name;
                $digest->addfile($in);
                my $checksum = $digest->hexdigest();
                close $in;

                open my ($out), ">", $md5_filename;
                printf $out "%s *%s", $checksum, $download_set->{'archive-name'};
                close $out;

                printf "    created MD5\n";
            }
        }
        else
        {
            printf "    MD5 already exists\n";
        }

        my $sha256_filename = $full_archive_name . ".sha256";
        if ( ! -f $sha256_filename || IsOlderThan($sha256_filename, $full_archive_name))
        {
            if ($context->{'dry-run'})
            {
                printf "    would create SHA256\n";
            }
            else
            {
                my $digest = Digest::SHA->new("sha256");
                open my ($in), $full_archive_name;
                $digest->addfile($in);
                my $checksum = $digest->hexdigest();
                close $in;

                open my ($out), ">", $sha256_filename;
                printf $out "%s *%s", $checksum, $download_set->{'archive-name'};
                close $out;

                printf "    created SHA256\n";
            }
        }
        else
        {
            printf "    SHA256 already exists\n";
        }

        my $asc_filename = $full_archive_name . ".asc";
        if ( ! -f $asc_filename || IsOlderThan($asc_filename, $full_archive_name))
        {
            if ($context->{'dry-run'})
            {
                printf "    would create ASC\n";
            }
            else
            {
                # gpg seems not to be able to sign more than one file at a time.
                # Password has to be provided every time.
                my $command = sprintf("gpg --armor --detach-sig \"%s\"", $full_archive_name);
                print $command;
                my $result = system($command);
                printf "    created ASC\n";
            }
        }
        else
        {
            printf "    ASC already exists\n";
        }
    }
}




=head2 IsOlderThan ($filename1, $filename2)

    Return true (1) if the last modification date of $filename1 is older than (<) that of $filename2.

=cut
sub IsOlderThan ($$)
{
    my ($filename1, $filename2) = @_;

    my @stat1 = stat $filename1;
    my @stat2 = stat $filename2;

    return $stat1[9] < $stat2[9];
}




sub GetInstallationPackageName ($$$$)
{
    my ($release_descriptor, $platform_package_descriptor, $package_format, $language) = @_;

    my $path = ResolveTemplate(
        $platform_package_descriptor->{'archive-path'},
        $release_descriptor,
        $platform_package_descriptor,
        $package_format,
        $language);
    my $name = ResolveTemplate(
        $platform_package_descriptor->{'archive-name'},
        $release_descriptor,
        $platform_package_descriptor,
        $package_format,
        $language);

    return ($path, $name);
}




sub ResolveTemplate ($$$$$)
{
    my ($template, $release_descriptor, $platform_package_descriptor, $package_format, $language) = @_;
    
    my $archive_package_type = "";
    if ($platform_package_descriptor->{'add-package-type-to-archive-name'} =~ /^(1|true|yes)$/i)
    {
        $archive_package_type = "-".$package_format;
    }
    my $full_language = $language;
    if ($EnUSBasedLanguages{$language})
    {
        $full_language = "en-US_".$language;
    }
    my $extension = $platform_package_descriptor->{'download-extension'};
    if ( ! defined $extension)
    {
        $extension = $platform_package_descriptor->{'extension'};
    }

    my $old_to_new_version_dash = sprintf(
        "v-%s_v-%s",
        $release_descriptor->{'previous-version'},
        $release_descriptor->{'version'});
    $old_to_new_version_dash =~ s/\./-/g;
    my $old_to_new_version_dots = sprintf(
        "%s-%s",
        $release_descriptor->{'previous-version'},
        $release_descriptor->{'version'});
    
    
    my $name = $template;
    
    # Resolve %? template parameters.
    $name =~ s/%V/$release_descriptor->{'version'}/g;
    $name =~ s/%W/$old_to_new_version_dash/g;
    $name =~ s/%w/$old_to_new_version_dots/g;
    $name =~ s/%P/$platform_package_descriptor->{'archive-platform'}/g;
    $name =~ s/%t/$archive_package_type/g;
    $name =~ s/%T/$package_format/g;
    $name =~ s/%l/$full_language/g;
    $name =~ s/%L/$language/g;
    $name =~ s/%E/$extension/g;

    # Resolve $name environment references.
    while ($name =~ /^(.*?)\$([a-zA-Z0-9_]+)(.*)$/)
    {
        $name = $1 . $ENV{$2} . $3;
    }

    return $name;
}




sub GetCurrentPlatformDescriptor ($)
{
    my ($release_descriptor) = @_;

    my $platform_descriptor = $release_descriptor->{'platforms'}->{$ENV{'INPATH'}};
    if ( ! defined $platform_descriptor)
    {
        printf STDERR "ERROR: platform '%s' is not supported\n", $ENV{'INPATH'};
    }
    return $platform_descriptor;
}




sub GetPlatformPackage ($$$)
{
    my ($release_descriptor, $platform_descriptor, $package_descriptor) = @_;
    my $key = sprintf("%s/%s", $platform_descriptor->{'id'}, $package_descriptor->{'id'});

    my $platform_package = $release_descriptor->{'platform-packages'}->{$key};
    $platform_package = {}
        unless defined $platform_package;
    
    my $joined_descriptor = {
        %$platform_descriptor,
        %$package_descriptor,
        %$platform_package,
        'id' => $key,
        'platform-id' => $platform_descriptor->{'id'},
        'package-id' => $package_descriptor->{'id'}
    };
    return $joined_descriptor;
}




sub Wiki ($$)
{
    my ($release_descriptor, $context) = @_;

    open my $out, ">", $context->{'output-filename'};

    my @table_list = GetTableList($release_descriptor);
    foreach my $table_name (@table_list)
    {
        my @table_packages = GetPackagesForTable($release_descriptor, $table_name);
        my @table_languages = GetLanguagesForTable($release_descriptor, @table_packages);
        my @table_platforms = GetPlatformsForTable($release_descriptor, @table_packages);

        printf "packages: %s\n", join(", ", map {$_->{'package'}->{'display-name'}} @table_packages);
        printf "languages: %s\n", join(", ", map {$_->{'english-name'}} @table_languages);
        printf "platforms: %s\n", join(", ", map {$_->{'id'}} @table_platforms);

        print $out "{| class=\"wikitable\"\n";

        # Write the table head.
        print $out "|-\n";
        print $out "! colspan=\"2\" | Language<br>The names do not refer to countries\n";
        print $out "! Type\n";
        foreach my $platform_descriptor (@table_platforms)
        {
            foreach my $package_type (@{$platform_descriptor->{'package-types'}})
            {
                printf $out "! %s<br>%s bit<br>%s\n",
                $platform_descriptor->{'display-name'},
                $platform_descriptor->{'word-size'},
                uc($package_type);
            }
        }

        foreach my $language_descriptor (@table_languages)
        {
            if ($context->{'check-links'})
            {
                $| = 1;
                printf "%-5s: ", $language_descriptor->{'id'};
            }

            print $out "|-\n";
            printf $out "| rowspan=\"%d\" | %s\n", scalar @table_packages, $language_descriptor->{'english-name'};
            printf $out "| rowspan=\"%d\" | %s\n", scalar @table_packages, $language_descriptor->{'local-name'};

            my $is_first = 1;
            foreach my $wiki_package_descriptor (@table_packages)
            {
                my $package_descriptor = $wiki_package_descriptor->{'package'};

                if ($is_first)
                {
                    $is_first = 0;
                }
                else
                {
                    printf $out "|-\n";
                }

                # Write the name of the package, e.g. Full Install or Langpack.
                if (defined $package_descriptor->{'link-URL'})
                {
                    printf $out "| [%s %s]\n",
                    $package_descriptor->{'link-URL'},
                    $package_descriptor->{'display-name'};
                }
                else
                {
                    printf $out "| %s\n", $package_descriptor->{'display-name'};
                }

                foreach my $platform_descriptor (@table_platforms)
                {
                    my $platform_package_descriptor = GetPlatformPackage(
                        $release_descriptor,
                        $platform_descriptor,
                        $package_descriptor);

                    foreach my $package_type (@{$platform_package_descriptor->{'package-types'}})
                    {
                        WriteDownloadLinks(
                            $out,
                            $release_descriptor,
                            $context,
                            $language_descriptor,
                            $wiki_package_descriptor,
                            $platform_package_descriptor,
                            $package_type);
                    }
                }
            }
            
            if ($context->{'check-links'})
            {
                printf "\n";
            }
        }

        print $out "|}\n";
    }
    close $out;
}




sub GetTableList ($)
{
    my ($release_descriptor) = @_;

    my %seen_table_names = ();
    my @table_names = ();
    foreach my $wiki_package_descriptor (@{$release_descriptor->{'wiki-packages'}})
    {
        my $table_name = $wiki_package_descriptor->{'table'};
        if ( ! $seen_table_names{$table_name})
        {
            push @table_names, $table_name;
            $seen_table_names{$table_name} = 1;
        }
    }
    return @table_names;
}




sub GetPackagesForTable ($$)
{
    my ($release_descriptor, $table_name) = @_;

    my @packages = ();
    foreach my $wiki_package_descriptor (@{$release_descriptor->{'wiki-packages'}})
    {
        if ($wiki_package_descriptor->{'table'} eq $table_name)
        {
            my $package_descriptor = $release_descriptor->{'packages'}->{
                $wiki_package_descriptor->{'package-id'}};
            $wiki_package_descriptor->{'package'} = $package_descriptor;
            push @packages, $wiki_package_descriptor;
        }
    }
    return @packages;
}




sub GetLanguagesForTable ($@)
{
    my ($release_descriptor, @packages) = @_;

    # Find the languages that are reference by at least one package.
    my %matching_languages = ();
    foreach my $package_descriptor (@packages)
    {
        foreach my $language_id (@{$package_descriptor->{'language-list'}})
        {
            $matching_languages{$language_id} = 1;
        }
    }

    # Retrieve the language descriptors for the language ids.
    my @matching_language_descriptors = ();
    foreach my $language_id (@{$release_descriptor->{'language-ids'}})
    {
        if (defined $matching_languages{$language_id})
        {
            my $language_descriptor = $release_descriptor->{'languages'}->{$language_id};
            if (defined $language_descriptor)
            {
                push @matching_language_descriptors, $language_descriptor;
            }
        }
    }

    return @matching_language_descriptors;
}




sub GetPlatformsForTable ($@)
{
    my ($release_descriptor, @packages) = @_;

    # Find the platforms that are reference by at least one package.
    my %matching_platform_ids = ();
    foreach my $package_descriptor (@packages)
    {
        foreach my $platform_id (@{$package_descriptor->{'platform-list'}})
        {
            $matching_platform_ids{$platform_id} = 1;
        }
    }

    # Retrieve the platform descriptors for the plaform ids.
    my @matching_platform_descriptors = ();
    foreach my $platform_id (@{$release_descriptor->{'platform-ids'}})
    {
        if ($matching_platform_ids{$platform_id})
        {
	    print $platform_id."\n";
            push @matching_platform_descriptors, $release_descriptor->{'platforms'}->{$platform_id};
        }
    }

    return @matching_platform_descriptors;
}




my $bold_text_start = "<b>";
my $bold_text_end = "</b>";
my $small_text_start = "<span style=\"font-size:80%\">";
my $small_text_end = "</span>";
my $broken_link_start = "<span style=\"color:#FF0000\">";
my $broken_link_end = "</span>";


sub WriteDownloadLinks ($$$$$$$)
{
    my ($out,
        $release_descriptor,
        $context,
        $language_descriptor,
        $wiki_package_descriptor,
        $platform_package_descriptor,
        $package_type) = @_;

    # Check if the current language and platform match the package.
    my $platform_id = $platform_package_descriptor->{'platform-id'};
    if (defined $wiki_package_descriptor->{'platforms'}->{$platform_id}
        && defined $wiki_package_descriptor->{'languages'}->{$language_descriptor->{'id'}})
    {
        my $archive_package_name = "";
        my $extension = $package_type;
        if (defined $platform_package_descriptor->{'extension'})
        {
            $extension = $platform_package_descriptor->{'extension'};
        }
        if (defined $platform_package_descriptor->{'download-extension'})
        {
            $extension = $platform_package_descriptor->{'download-extension'};
        }
        $archive_package_name = "-".$package_type if ($package_type =~ /deb|rpm/);

        my ($archive_path, $archive_name) = GetInstallationPackageName(
            $release_descriptor,
            $platform_package_descriptor,
            $package_type,
            $language_descriptor->{'id'});

        printf $out "| align=\"center\" | ";
        my $download = FindDownload(
            $context,
            $release_descriptor,
            $platform_package_descriptor,
            $package_type,
            $archive_name);
        if (defined $download)
        {
            my $url = $download->{'base-url'} . "/". $archive_name;
            printf $out "%s%s%s<br><br>%s%s %s<br>%s%s",
            $bold_text_start,
            CreateLink($url, $extension, $context),
            $bold_text_end,
            $small_text_start,
            CreateLink($url.".asc", "ASC", $context),
            CreateLink($url.".md5", "MD5", $context),
            CreateLink($url.".sha256", "SHA256", $context),
            $small_text_end;
        }
        printf $out "\n";
    }
    else
    {
        printf $out "|\n";
    }
}




sub FindDownload ($$$$$)
{
    my ($context,
        $release_descriptor,
        $platform_package_descriptor,
        $package_type,
        $archive_name) = @_;

    foreach my $download (@{$release_descriptor->{'downloads'}})
    {
        if ($download->{'platform-id'} eq $platform_package_descriptor->{'platform-id'})
        {
            my $url = $download->{'base-url'} . "/". $archive_name;
            if ($context->{'check-links'})
            {
                if (CheckLink($url))
                {
                    # URL points to an existing file.
                    printf "+";
                    return $download;
                }
                else
                {
                    # URL is broken.
                    # Try the next download area for the platform.
                    next;
                }
            }
            else
            {
                # Use the URL unchecked.  If there is more than one download area for the platform then only
                # the first is ever used.
                printf ".";
                return $download;
            }
        }
    }

    if ($context->{'check-links'})
    {
        printf "-";
    }

    return undef;
}




sub CreateLink ($$$)
{
    my ($url, $text, $context) = @_;

    my $is_link_broken = 0;
    if ($context->{'check-links'})
    {
        if (CheckLink($url))
        {
            $is_link_broken = 0;
            printf "+";
        }
        else
        {
            $is_link_broken = 1;
            printf "-";
        }
    }
    else
    {
        printf ".";
    }

    if ( ! $is_link_broken)
    {
        return sprintf ("[%s %s]", $url, $text);
    }
    elsif ($context->{'mark-broken-links'})
    {
        return sprintf ("%sbroken%s[%s %s]", $broken_link_start, $broken_link_end, $url, $text);
    }
    else
    {
        return sprintf ("%s", $text);
    }
}




=head2 CheckLink ($url)

    Check if the file referenced by $url can be downloaded.
    This is determined by downloading only the header.
    
=cut
my $LastCheckedURL = "";
my $LastCheckedResult = undef;
sub CheckLink ($)
{
    my ($url) = @_;

    if ($url ne $LastCheckedURL)
    {
        my $head = LWP::Simple::head($url);
        $LastCheckedURL = $url;
        $LastCheckedResult = !!$head;
    }

    return $LastCheckedResult;
}




sub SignFile ($$)
{
    my ($signature, $filename) = @_;

    my $command = sprintf(
        "gpg --armor --output %s.asc --detach-sig %s",
        $filename,
        $filename);
}




my $context = ProcessCommandline(@ARGV);
my $release_descriptor = ReadReleaseDescription($context->{'filename'}, $context);
if ($context->{'command'} eq "build")
{
    WriteMakefile($release_descriptor, $context);
}
elsif ($context->{'command'} eq "upload")
{
    Upload($release_descriptor, $context);
}
elsif ($context->{'command'} eq "wiki")
{
    Wiki($release_descriptor, $context);
}
