#!/usr/bin/perl -w

#**************************************************************
#
#  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 Getopt::Long;
use Pod::Usage;
use File::Path;
use File::Spec;
use File::Basename;
use XML::LibXML;
use Digest;
use Archive::Zip;
use Archive::Extract;

use installer::ziplist;
use installer::logger;
use installer::windows::msiglobal;
use installer::patch::Msi;
use installer::patch::ReleasesList;
use installer::patch::Version;

#use Carp::Always;

use strict;


=head1 NAME

    patch_tool.pl - Create Windows MSI patches.

=head1 SYNOPSIS

    patch_tool.pl command [options]

    Commands:
        create    create patches
        apply     apply patches

    Options:
        -p|--product-name <product-name>
             The product name, eg Apache_OpenOffice
        -o|--output-path <path>
             Path to the instsetoo_native platform output tree
        -d|--data-path <path>
             Path to the data directory that is expected to be under version control.
        --source-version <major>.<minor>.<micro>
             The version that is to be patched.
        --target-version <major>.<minor>.<micro>
             The version after the patch has been applied.
        --language <language-code>
             Language of the installation sets.
        --package-format
             Only the package format 'msi' is supported at the moment.

=head1 DESCRIPTION

    Creates windows MSP patch files, one for each relevant language.
    Patches convert an installed OpenOffice to the target version.

    Required data are:
        Installation sets of the source versions
            Taken from ext_sources/
            Downloaded from archive.apache.org on demand

        Installation set of the target version
            This is expected to be the current version.

=cut

# The ImageFamily name has to have 1-8 alphanumeric characters.
my $ImageFamily = "AOO";
my $SourceImageName = "Source";
my $TargetImageName = "Target";



sub ProcessCommandline ()
{
    my $context = {
        'product-name' => undef,
        'output-path' => undef,
        'data-path' => undef,
        'lst-file' => undef,
        'source-version' => undef,
        'target-version' => undef,
        'language' => undef,
        'package-format' => undef
    };

    if ( ! GetOptions(
               "product-name=s", \$context->{'product-name'},
               "output-path=s", \$context->{'output-path'},
               "data-path=s" => \$context->{'data-path'},
               "lst-file=s" => \$context->{'lst-file'},
               "source-version:s" => \$context->{'source-version'},
               "target-version:s" => \$context->{'target-version'},
               "language=s" => \$context->{'language'},
               "package-format=s" => \$context->{'package-format'}
        ))
    {
        pod2usage(2);
    }

    # Only the command should be left in @ARGV.
    pod2usage(2) unless scalar @ARGV == 1;
    $context->{'command'} = shift @ARGV;

    return $context;
}




sub GetSourceMsiPath ($$)
{
    my ($context, $language) = @_;
    my $unpacked_path = File::Spec->catfile(
	$context->{'output-path'},
	$context->{'product-name'},
        $context->{'package-format'},
	installer::patch::Version::ArrayToDirectoryName(
	    installer::patch::Version::StringToNumberArray(
		$context->{'source-version'})),
	$language);
}




sub GetTargetMsiPath ($$)
{
    my ($context, $language) = @_;
    return File::Spec->catfile(
        $context->{'output-path'},
        $context->{'product-name'},
        $context->{'package-format'},
        "install",
        $language);
}



sub ProvideInstallationSets ($$)
{
    my ($context, $language) = @_;

    # Assume that the target installation set is located in the output tree.
    my $target_path = GetTargetMsiPath($context, $language);
    if ( ! -d $target_path)
    {
        installer::logger::PrintError("can not find target installation set at '%s'\n", $target_path);
        return 0;
    }
    my @target_version = installer::patch::Version::StringToNumberArray($context->{'target-version'});
    my $target_msi_file = File::Spec->catfile(
        $target_path,
        sprintf("openoffice%d%d%d.msi", $target_version[0], $target_version[1], $target_version[2]));
    if ( ! -f $target_msi_file)
    {
        installer::logger::PrintError("can not find target msi file at '%s'\n", $target_msi_file);
        return 0;
    }

    return 1;
}




sub IsLanguageValid ($$$)
{
    my ($context, $release_data, $language) = @_;

    my $normalized_language = installer::languages::get_normalized_language($language);

    if ( ! ProvideInstallationSets($context, $language))
    {
        installer::logger::PrintError("    '%s' has no target installation set\n", $language);
        return 0;
    }
    elsif ( ! defined $release_data->{$normalized_language})
    {
        installer::logger::PrintError("    '%s' is not a released language for version %s\n",
            $language,
            $context->{'source-version'});
        return 0;
    }
    else
    {
        return 1;
    }
}




sub ProvideSourceInstallationSet ($$$)
{
    my ($context, $language, $release_data) = @_;

    my $url = $release_data->{$language}->{'URL'};
    $url =~ /^(.*)\/([^\/]*)$/;
    my ($location, $basename) = ($1,$2);

    my $ext_sources_path = $ENV{'TARFILE_LOCATION'};
    if ( ! -d $ext_sources_path)
    {
        installer::logger::PrintError("Can not determine the path to ext_sources/.\n");
        installer::logger::PrintError("Maybe SOURCE_ROOT_DIR has not been correctly set in the environment?");
        return 0;
    }

    # We need the unpacked installation set in <platform>/<product>/<package>/<source-version>,
    # eg wntmsci12.pro/Apache_OpenOffice/msi/v-4-0-0.
    my $unpacked_path = GetSourceMsiPath($context, $language);
    if ( ! -d $unpacked_path)
    {
        # Make sure that the downloadable installation set (.exe) is present in ext_sources/.
        my $filename = File::Spec->catfile($ext_sources_path, $basename);
        if ( -f $filename)
        {
            PrintInfo("%s is already present in ext_sources/.  Nothing to do\n", $basename);
        }
        else
        {
            return 0 if ! installer::patch::InstallationSet::Download(
                $language,
                $release_data,
                $filename);
            return 0 if ! -f $filename;
        }

        # Unpack the installation set.
        if ( -d $unpacked_path)
        {
            # Take the existence of the destination path as proof that the
            # installation set was successfully unpacked before.
        }
        else
        {
            installer::patch::InstallationSet::Unpack($filename, $unpacked_path);
        }
    }
}




# Find the source and target version between which the patch will be
# created.  Typically the target version is the current version and
# the source version is the version of the previous release.
sub DetermineVersions ($$)
{
    my ($context, $variables) = @_;

    if (defined $context->{'source-version'} && defined $context->{'target-version'})
    {
        # Both source and target version have been specified on the
        # command line. There remains nothing to be done.
        return;
    }

    if ( ! defined $context->{'target-version'})
    {
        # Use the current version as target version.
        $context->{'target-version'} = $variables->{PRODUCTVERSION};
    }

    my @target_version = installer::patch::Version::StringToNumberArray($context->{'target-version'});
    shift @target_version;
    my $is_target_version_major = 1;
    foreach my $number (@target_version)
    {
        $is_target_version_major = 0 if ($number ne "0");
    }
    if ($is_target_version_major)
    {
        installer::logger::PrintError("can not create patch where target version is a new major version (%s)\n",
            $context->{'target-version'});
        die;
    }

    if ( ! defined $context->{'source-version'})
    {
        my $releases = installer::patch::ReleasesList::Instance();

        # Search for target release in the list of previous releases.
        # If it is found, use the previous version as source version.
        # Otherwise use the last released version.
        my $last_release = undef;
        foreach my $release (@{$releases->{'releases'}})
        {
            last if ($release eq $context->{'target-version'});
            $last_release = $release;
        }
        $context->{'source-version'} = $last_release;
    }

    if (defined $context->{'source-version'})
    {
        $context->{'source-version-dash'} = installer::patch::Version::ArrayToDirectoryName(
            installer::patch::Version::StringToNumberArray(
                $context->{'source-version'}));
    }
    if (defined $context->{'target-version'})
    {
        $context->{'target-version-dash'} = installer::patch::Version::ArrayToDirectoryName(
            installer::patch::Version::StringToNumberArray(
                $context->{'target-version'}));
    }
}




=head2 CheckUpgradeCode($source_msi, $target_msi)

    The 'UpgradeCode' values in the 'Property' table differs from source to target

=cut
sub CheckUpgradeCode($$)
{
    my ($source_msi, $target_msi) = @_;

    my $source_upgrade_code = $source_msi->GetTable("Property")->GetValue("Property", "UpgradeCode", "Value");
    my $target_upgrade_code = $target_msi->GetTable("Property")->GetValue("Property", "UpgradeCode", "Value");

    if ($source_upgrade_code eq $target_upgrade_code)
    {
        $installer::logger::Info->printf("Error: The UpgradeCode properties have to differ but are both '%s'\n",
            $source_upgrade_code);
        return 0;
    }
    else
    {
        $installer::logger::Info->printf("OK: UpgradeCode values are different\n");
        return 1;
    }
}




=head2 CheckProductCode($source_msi, $target_msi)

    The 'ProductCode' values in the 'Property' tables remain the same.

=cut
sub CheckProductCode($$)
{
    my ($source_msi, $target_msi) = @_;

    my $source_product_code = $source_msi->GetTable("Property")->GetValue("Property", "ProductCode", "Value");
    my $target_product_code = $target_msi->GetTable("Property")->GetValue("Property", "ProductCode", "Value");

    if ($source_product_code ne $target_product_code)
    {
        $installer::logger::Info->printf("Error: The ProductCode properties have to remain the same but are\n");
        $installer::logger::Info->printf("       '%s' and '%s'\n",
            $source_product_code,
            $target_product_code);
        return 0;
    }
    else
    {
        $installer::logger::Info->printf("OK: ProductCodes are identical\n");
        return 1;
    }
}




=head2 CheckBuildIdCode($source_msi, $target_msi)

    The 'PRODUCTBUILDID' values in the 'Property' tables (not the AOO build ids) differ and the
    target value is higher than the source value.

=cut
sub CheckBuildIdCode($$)
{
    my ($source_msi, $target_msi) = @_;

    my $source_build_id = $source_msi->GetTable("Property")->GetValue("Property", "PRODUCTBUILDID", "Value");
    my $target_build_id = $target_msi->GetTable("Property")->GetValue("Property", "PRODUCTBUILDID", "Value");

    if ($source_build_id >= $target_build_id)
    {
        $installer::logger::Info->printf(
            "Error: The PRODUCTBUILDID properties have to increase but are '%s' and '%s'\n",
            $source_build_id,
            $target_build_id);
        return 0;
    }
    else
    {
        $installer::logger::Info->printf("OK: source build id is lower than target build id\n");
        return 1;
    }
}




sub CheckProductName ($$)
{
    my ($source_msi, $target_msi) = @_;

    my $source_product_name = $source_msi->GetTable("Property")->GetValue("Property", "DEFINEDPRODUCT", "Value");
    my $target_product_name = $target_msi->GetTable("Property")->GetValue("Property", "DEFINEDPRODUCT", "Value");

    if ($source_product_name ne $target_product_name)
    {
        $installer::logger::Info->printf("Error: product names of are not identical:\n");
        $installer::logger::Info->printf("       %s != %s\n", $source_product_name, $target_product_name);
        return 0;
    }
    else
    {
        $installer::logger::Info->printf("OK: product names are identical\n");
        return 1;
    }
}




=head2 CheckRemovedFiles($source_msi, $target_msi)

    Files and components must not be deleted.

=cut
sub CheckRemovedFiles($$)
{
    my ($source_msi, $target_msi) = @_;

    # Get the 'File' tables.
    my $source_file_table = $source_msi->GetTable("File");
    my $target_file_table = $target_msi->GetTable("File");

    # Create data structures for fast lookup.
    my @source_files = map {$_->GetValue("File")} @{$source_file_table->GetAllRows()};
    my %target_file_map = map {$_->GetValue("File") => $_} @{$target_file_table->GetAllRows()};

    # Search for removed files (files in source that are missing from target).
    my $removed_file_count = 0;
    foreach my $uniquename (@source_files)
    {
        if ( ! defined $target_file_map{$uniquename})
        {
            ++$removed_file_count;
        }
    }

    if ($removed_file_count > 0)
    {
        $installer::logger::Info->printf("Error: %d files have been removed\n", $removed_file_count);
        return 0;
    }
    else
    {
        $installer::logger::Info->printf("OK: no files have been removed\n");
        return 1;
    }
}




=head2 CheckNewFiles($source_msi, $target_msi)

    New files have to be in new components.

=cut
sub CheckNewFiles($$)
{
    my ($source_msi, $target_msi) = @_;

    # Get the 'File' tables.
    my $source_file_table = $source_msi->GetTable("File");
    my $target_file_table = $target_msi->GetTable("File");

    # Create data structures for fast lookup.
    my %source_file_map = map {$_->GetValue("File") => $_} @{$source_file_table->GetAllRows()};
    my %target_files_map = map {$_->GetValue("File") => $_} @{$target_file_table->GetAllRows()};

    # Search for added files (files in target that where not in source).
    my @added_files = ();
    foreach my $uniquename (keys %target_files_map)
    {
        if ( ! defined $source_file_map{$uniquename})
        {
            push @added_files, $target_files_map{$uniquename};
        }
    }

    if (scalar @added_files > 0)
    {
        $installer::logger::Info->printf("Warning: %d files have been added\n", scalar @added_files);

        # Prepare component tables and hashes.
        my $source_component_table = $source_msi->GetTable("Component");
        my $target_component_table = $target_msi->GetTable("Component");
        die unless defined $source_component_table && defined $target_component_table;
        my %source_component_map = map {$_->GetValue('Component') => $_} @{$source_component_table->GetAllRows()};
        my %target_component_map = map {$_->GetValue('Component') => $_} @{$target_component_table->GetAllRows()};

        my @new_files_with_existing_components = ();
        foreach my $target_file_row (@added_files)
        {
	    $installer::logger::Info->printf("    %s (%s)\n",
		$target_file_row->GetValue("FileName"),
		$target_file_row->GetValue("File"));

            # Get target component for target file.
            my $target_component = $target_file_row->GetValue('Component_');

            # Check that the component is not part of the source components.
            if (defined $source_component_map{$target_component})
            {
                push @new_files_with_existing_components, $target_file_row;
            }
        }

        if (scalar @new_files_with_existing_components > 0)
        {
            $installer::logger::Info->printf(
                "Error: %d new files have existing components (which must also be new)\n",
                scalar @new_files_with_existing_components);
            return 0;
        }
        else
        {
            $installer::logger::Info->printf(
                "OK: all %d new files also have new components\n",
		scalar @added_files);
            return 1;
        }
    }
    else
    {
        $installer::logger::Info->printf("OK: no files have been added\n");
        return 1;
    }
}




=head2 CheckFeatureSets($source_msi, $target_msi)

    Features must not be removed but can be added.
    Parent features of new features also have to be new.

=cut
sub CheckFeatureSets($$)
{
    my ($source_msi, $target_msi) = @_;

    # Get the 'Feature' tables.
    my $source_feature_table = $source_msi->GetTable("Feature");
    my $target_feature_table = $target_msi->GetTable("Feature");

    # Create data structures for fast lookup.
    my %source_feature_map = map {$_->GetValue("Feature") => $_} @{$source_feature_table->GetAllRows()};
    my %target_feature_map = map {$_->GetValue("Feature") => $_} @{$target_feature_table->GetAllRows()};

    # Check that no feature has been removed.
    my @removed_features = ();
    foreach my $feature_name (keys %source_feature_map)
    {
        if ( ! defined $target_feature_map{$feature_name})
        {
            push @removed_features, $feature_name;
        }
    }
    if (scalar @removed_features > 0)
    {
        # There are removed features.
        $installer::logger::Info->printf(
            "Error: %d features have been removed:\n",
            scalar @removed_features);
        $installer::logger::Info->printf("       %s\n", join(", ", @removed_features));
        return 0;
    }

    # Check that added features belong to new parent features.
    my @added_features = ();
    foreach my $feature_name (keys %target_feature_map)
    {
        if ( ! defined $source_feature_map{$feature_name})
        {
            push @added_features, $feature_name;
        }
    }

    if (scalar @added_features > 0)
    {
        $installer::logger::Info->printf("Warning: %d features have been added\n", scalar @added_features);

        my @new_features_with_existing_parents = ();
        foreach my $new_feature (@added_features)
        {
            my $target_feature = $target_feature_map{$new_feature};
            if (defined $source_feature_map{$target_feature->{'Feature_Parent'}})
            {
                push @new_features_with_existing_parents, $target_feature;
            }
        }

        if (scalar @new_features_with_existing_parents > 0)
        {
            $installer::logger::Info->printf(
                "Error: %d new features have existing parents (which also must be new)\n",
                scalar @new_features_with_existing_parents);
            return 0;
        }
        else
        {
            $installer::logger::Info->printf(
                "OK: parents of all new features are also new\n");
            return 1;
        }
    }

    $installer::logger::Info->printf("OK: feature sets in source and target are compatible\n");
    return 1;
}




=head2 CheckRemovedComponents($source_msi, $target_msi)

    Components must not be removed but can be added.
    Features of added components have also to be new.

=cut
sub CheckRemovedComponents ($$)
{
    my ($source_msi, $target_msi) = @_;

    # Get the 'Component' tables.
    my $source_component_table = $source_msi->GetTable("Component");
    my $target_component_table = $target_msi->GetTable("Component");

    # Create data structures for fast lookup.
    my %source_component_map = map {$_->GetValue("Component") => $_} @{$source_component_table->GetAllRows()};
    my %target_component_map = map {$_->GetValue("Component") => $_} @{$target_component_table->GetAllRows()};

    # Check that no component has been removed.
    my @removed_components = ();
    foreach my $componentname (keys %source_component_map)
    {
        if ( ! defined $target_component_map{$componentname})
        {
            push @removed_components, $componentname;
        }
    }
    if (scalar @removed_components == 0)
    {
	$installer::logger::Info->printf("OK: no removed components\n");
	return 1;
    }
    else
    {
        # There are removed components.

        # Check if any of them is not a registry component.
        my $is_file_component_removed = 0;
        foreach my $componentname (@removed_components)
        {
            if ($componentname !~ /^registry/)
            {
                $is_file_component_removed = 1;
            }
        }
        if ($is_file_component_removed)
        {
            $installer::logger::Info->printf(
                "Error: %d components have been removed, some of them are file components:\n",
                scalar @removed_components);
            $installer::logger::Info->printf("       %s\n", join(", ", @removed_components));
            return 0;
        }
        else
        {
            $installer::logger::Info->printf(
                "Error: %d components have been removed, all of them are registry components:\n",
                scalar @removed_components);
            return 0;
        }
    }
}




sub GetTableAndMap ($$$)
{
    my ($msi, $table_name, $index_column) = @_;

    my $table = $msi->GetTable($table_name);
    my %map = map {$_->GetValue($index_column) => $_} @{$table->GetAllRows()};

    return ($table, \%map);
}


=head2 CheckAddedComponents($source_msi, $target_msi)

    Components can be added.
    Features of added components have also to be new.

=cut
sub CheckAddedComponents ($$)
{
    my ($source_msi, $target_msi) = @_;

    # Get the 'Component' tables and maps.
    my ($source_component_table, $source_component_map)
	= GetTableAndMap($source_msi, "Component", "Component");
    my ($target_component_table, $target_component_map)
	= GetTableAndMap($target_msi, "Component", "Component");

    # Check that added components belong to new features.
    my @added_components = ();
    foreach my $componentname (keys %$target_component_map)
    {
        if ( ! defined $source_component_map->{$componentname})
        {
            push @added_components, $componentname;
        }
    }

    if (scalar @added_components == 0)
    {
	$installer::logger::Info->printf("OK: no new components\n");
	return 1;
    }
    else
    {
	$installer::logger::Info->printf(
	    "Warning: %d components have been added\n",
	    scalar @added_components);

        # Check that the referencing features are also new.
	my $target_feature_component_table = $target_msi->GetTable("FeatureComponents");

	my $error = 0;
        foreach my $component_name (@added_components)
        {
	    my @feature_names = ();
	    foreach my $feature_component_row (@{$target_feature_component_table->GetAllRows()})
	    {
		if ($feature_component_row->GetValue("Component_") eq $component_name)
		{
		    my $feature_name = $feature_component_row->GetValue("Feature_");
		    push @feature_names, $feature_name;
		}
	    }
	    if (scalar @feature_names == 0)
	    {
		$installer::logger::Info->printf("Error: no feature found for component '%s'\n", $component_name);
		$error = 1;
	    }
	    else
	    {
		# Check that the referenced features are new and have new parents (if they have parents).
		my ($source_feature_table, $source_feature_map)
		    = GetTableAndMap($source_msi, "Feature", "Feature");
		my ($target_feature_table, $target_feature_map)
		    = GetTableAndMap($target_msi, "Feature", "Feature");
		foreach my $feature_name (@feature_names)
		{
		    $installer::logger::Info->printf("    component '%s' -> feature '%s'\n",
			$component_name,
			$feature_name);
		    my $source_feature_row = $source_feature_map->{$feature_name};
		    if (defined $source_feature_row)
		    {
			$installer::logger::Info->printf("Warning(Error?): feature of new component is not new\n");
			$error = 1;
		    }
		    else
		    {
			# Feature is new. Check that the parent feature is also new.
			my $target_feature_row = $target_feature_map->{$feature_name};
			my $parent_feature_name = $target_feature_row->GetValue("Feature_Parent");
			if ($parent_feature_name ne "" && defined $source_feature_map->{$parent_feature_name})
			{
			    $installer::logger::Info->printf("Warning(Error?): parent feature of new component is not new\n");
			    $error = 1;
			}
		    }
		}
	    }
	}

#	return !$error;
	return 1;
    }
}




=head2 CheckComponent($source_msi, $target_msi)

    In the 'Component' table the 'ComponentId' and 'Component' values
    for corresponding componts in the source and target release have
    to be identical.

=cut
sub CheckComponentValues($$$)
{
    my ($source_msi, $target_msi, $variables) = @_;

    # Get the 'Component' tables.
    my $source_component_table = $source_msi->GetTable("Component");
    my $target_component_table = $target_msi->GetTable("Component");

    # Create data structures for fast lookup.
    my %source_component_map = map {$_->GetValue("Component") => $_} @{$source_component_table->GetAllRows()};
    my %target_component_map = map {$_->GetValue("Component") => $_} @{$target_component_table->GetAllRows()};

    my @differences = ();
    my $comparison_count = 0;
    while (my ($componentname, $source_component_row) = each %source_component_map)
    {
        my $target_component_row = $target_component_map{$componentname};
        if (defined $target_component_row)
        {
            ++$comparison_count;
            if ($source_component_row->GetValue("ComponentId") ne $target_component_row->GetValue("ComponentId"))
            {
                push @differences, [
                    $componentname,
                    $source_component_row->GetValue("ComponentId"),
                    $target_component_row->GetValue("ComponentId"),
                    $target_component_row->GetValue("Component"),
                ];
            }
        }
    }

    if (scalar @differences > 0)
    {
        $installer::logger::Info->printf(
            "Error: there are %d components with different 'ComponentId' values after %d comparisons.\n",
            scalar @differences,
            $comparison_count);
        foreach my $item (@differences)
        {
            $installer::logger::Info->printf("%s  %s\n", $item->[1], $item->[2]);
        }
        return 0;
    }
    else
    {
        $installer::logger::Info->printf("OK: components in source and target are identical\n");
        return 1;
    }
}




=head2 CheckFileSequence($source_msi, $target_msi)

    In the 'File' table the 'Sequence' numbers for corresponding files has to be identical.

=cut
sub CheckFileSequence($$)
{
    my ($source_msi, $target_msi) = @_;

    # Get the 'File' tables.
    my $source_file_table = $source_msi->GetTable("File");
    my $target_file_table = $target_msi->GetTable("File");

    # Create temporary data structures for fast access.
    my %source_file_map = map {$_->GetValue("File") => $_} @{$source_file_table->GetAllRows()};
    my %target_file_map = map {$_->GetValue("File") => $_} @{$target_file_table->GetAllRows()};

    # Search files with mismatching sequence numbers.
    my @mismatching_files = ();
    while (my ($uniquename,$source_file_row) = each %source_file_map)
    {
        my $target_file_row = $target_file_map{$uniquename};
        if (defined $target_file_row)
        {
            if ($source_file_row->GetValue('Sequence') ne $target_file_row->GetValue('Sequence'))
            {
                push @mismatching_files, [
                    $uniquename,
                    $source_file_row,
                    $target_file_row
                ];
            }
        }
    }

    if (scalar @mismatching_files > 0)
    {
        $installer::logger::Info->printf("Error: there are %d files with mismatching 'Sequence' numbers\n",
            scalar @mismatching_files);
        foreach my $item (@mismatching_files)
        {
            $installer::logger::Info->printf("    %s: %d != %d\n",
                $item->[0],
                $item->[1]->GetValue("Sequence"),
                $item->[2]->GetValue("Sequence"));
        }
        return 0;
    }
    else
    {
        $installer::logger::Info->printf("OK: all files have matching 'Sequence' numbers\n");
        return 1;
    }
}




=head2 CheckFileSequenceUnique($source_msi, $target_msi)

    In the 'File' table the 'Sequence' values have to be unique.

=cut
sub CheckFileSequenceUnique($$)
{
    my ($source_msi, $target_msi) = @_;

    # Get the 'File' tables.
    my $target_file_table = $target_msi->GetTable("File");

    my %sequence_numbers = ();
    my $collision_count = 0;
    foreach my $row (@{$target_file_table->GetAllRows()})
    {
        my $sequence_number = $row->GetValue("Sequence");
        if (defined $sequence_numbers{$sequence_number})
        {
            ++$collision_count;
        }
        else
        {
            $sequence_numbers{$sequence_number} = 1;
        }
    }

    if ($collision_count > 0)
    {
        $installer::logger::Info->printf("Error: there are %d collisions ofn the sequence numbers\n",
            $collision_count);
        return 0;
    }
    else
    {
        $installer::logger::Info->printf("OK: sequence numbers are unique\n");
        return 1;
    }
}




=head2 CheckFileSequenceHoles ($target_msi)

    Check the sequence numbers of the target msi if the n files use numbers 1..n or if there are holes.
    Holes are reported as warnings.

=cut
sub CheckFileSequenceHoles ($$)
{
    my ($source_msi, $target_msi) = @_;

    my $target_file_table = $target_msi->GetTable("File");
    my %sequence_numbers = map {$_->GetValue("Sequence") => $_} @{$target_file_table->GetAllRows()};
    my @sorted_sequence_numbers = sort {$a <=> $b} keys %sequence_numbers;
    my $expected_next_sequence_number = 1;
    my @holes = ();
    foreach my $sequence_number (@sorted_sequence_numbers)
    {
        if ($sequence_number != $expected_next_sequence_number)
        {
            push @holes, [$expected_next_sequence_number, $sequence_number-1];
        }
        $expected_next_sequence_number = $sequence_number+1;
    }
    if (scalar @holes > 0)
    {
        $installer::logger::Info->printf("Warning: sequence numbers have %d holes\n");
        foreach my $hole (@holes)
        {
            if ($hole->[0] != $hole->[1])
            {
                $installer::logger::Info->printf("    %d\n", $hole->[0]);
            }
            else
            {
                $installer::logger::Info->printf("    %d -> %d\n", $hole->[0], $hole->[1]);
            }
        }
    }
    else
    {
        $installer::logger::Info->printf("OK: there are no holes in the sequence numbers\n");
    }
    return 1;
}




=head2 CheckRegistryItems($source_msi, $target_msi)

    In the 'Registry' table the 'Component_' and 'Key' values must not
    depend on the version number (beyond the unchanging major
    version).

    'Value' values must only depend on the major version number to
    avoid duplicate entries in the start menu.

    Violations are reported as warnings for now.

=cut
sub CheckRegistryItems($$$)
{
    my ($source_msi, $target_msi, $product_name) = @_;

    # Get the registry tables.
    my $source_registry_table = $source_msi->GetTable("Registry");
    my $target_registry_table = $target_msi->GetTable("Registry");

    my $registry_index = $target_registry_table->GetColumnIndex("Registry");
    my $component_index = $target_registry_table->GetColumnIndex("Component_");

    # Create temporary data structures for fast access.
    my %source_registry_map = map {$_->GetValue($registry_index) => $_} @{$source_registry_table->GetAllRows()};
    my %target_registry_map = map {$_->GetValue($registry_index) => $_} @{$target_registry_table->GetAllRows()};

    # Prepare version numbers to search.
    my $source_version_number = $source_msi->{'version'};
    my $source_version_nodots = installer::patch::Version::ArrayToNoDotName(
        installer::patch::Version::StringToNumberArray($source_version_number));
    my $source_component_pattern = lc($product_name).$source_version_nodots;
    my $target_version_number = $target_msi->{'version'};
    my $target_version_nodots = installer::patch::Version::ArrayToNoDotName(
        installer::patch::Version::StringToNumberArray($target_version_number));
    my $target_component_pattern = lc($product_name).$target_version_nodots;

    foreach my $source_row (values %source_registry_map)
    {
        my $target_row = $target_registry_map{$source_row->GetValue($registry_index)};
        if ( ! defined $target_row)
        {
            $installer::logger::Info->printf("Error: sets of registry entries differs\n");
            return 1;
        }

        my $source_component_name = $source_row->GetValue($component_index);
        my $target_component_name = $source_row->GetValue($component_index);

    }

    $installer::logger::Info->printf("OK: registry items are OK\n");
    return 1;
}




=head2

    Component->KeyPath must not change. (see component.pm/get_component_keypath)

=cut
sub CheckComponentKeyPath ($$)
{
    my ($source_msi, $target_msi) = @_;

    # Get the registry tables.
    my $source_component_table = $source_msi->GetTable("Component");
    my $target_component_table = $target_msi->GetTable("Component");

    # Create temporary data structures for fast access.
    my %source_component_map = map {$_->GetValue("Component") => $_} @{$source_component_table->GetAllRows()};
    my %target_component_map = map {$_->GetValue("Component") => $_} @{$target_component_table->GetAllRows()};

    my @mismatches = ();
    while (my ($componentname, $source_component_row) = each %source_component_map)
    {
        my $target_component_row = $target_component_map{$componentname};
        if (defined $target_component_row)
        {
            my $source_keypath = $source_component_row->GetValue("KeyPath");
            my $target_keypath = $target_component_row->GetValue("KeyPath");
            if ($source_keypath ne $target_keypath)
            {
                push @mismatches, [$componentname, $source_keypath, $target_keypath];
            }
        }
    }

    if (scalar @mismatches > 0)
    {
        $installer::logger::Info->printf(
            "Error: there are %d mismatches in the 'KeyPath' column of the 'Component' table\n",
            scalar @mismatches);

        foreach my $item (@mismatches)
        {
            $installer::logger::Info->printf(
                "    %s: %s != %s\n",
                $item->[0],
                $item->[1],
                $item->[2]);
        }

        return 0;
    }
    else
    {
        $installer::logger::Info->printf(
            "OK: no mismatches in the 'KeyPath' column of the 'Component' table\n");
        return 1;
    }
}




sub GetMissingReferences ($$$$$)
{
    my ($table, $key, $map, $what, $report_key) = @_;

    my @missing_references = ();

    foreach my $row (@{$table->GetAllRows()})
    {
        my $value = $row->GetValue($key);
        if ($value ne "" && ! defined $map->{$value})
        {
            push @missing_references, [$what, $row->GetValue($report_key), $value];
        }
    }

    return @missing_references;
}




=head CheckAllReferences ($msi)

    Check references from files and registry entries to components,
    from components to features, and between features.

=cut

sub CheckAllReferences ($)
{
    my ($msi) = @_;

    # Set up tables and maps for easy iteration and fast lookups.

    my $feature_table = $msi->GetTable("Feature");
    my $component_table = $msi->GetTable("Component");
    my $feature_component_table = $msi->GetTable("FeatureComponents");
    my $file_table = $msi->GetTable("File");
    my $registry_table = $msi->GetTable("Registry");
    my $directory_table = $msi->GetTable("Directory");

    my %feature_map = map {$_->GetValue("Feature") => $_} @{$feature_table->GetAllRows()};
    my %component_map = map {$_->GetValue("Component") => $_} @{$component_table->GetAllRows()};
    my %directory_map = map {$_->GetValue("Directory") => $_} @{$directory_table->GetAllRows()};

    my @missing_references = ();

    # Check references from files and registry entries to components.
    push @missing_references, GetMissingReferences(
        $file_table,
        "Component_",
        \%component_map,
        "file->component",
        "File");
    push @missing_references, GetMissingReferences(
        $registry_table,
        "Component_",
        \%component_map,
        "registry->component",
        "Registry");

    # Check references between features and components.
    push @missing_references, GetMissingReferences(
        $feature_component_table,
        "Feature_",
        \%feature_map,
        "component->feature",
        "Component_");
    push @missing_references, GetMissingReferences(
        $feature_component_table,
        "Component_",
        \%component_map,
        "feature->component",
        "Feature_");

    # Check references between features.
    push @missing_references, GetMissingReferences(
        $feature_table,
        'Feature_Parent',
        \%feature_map,
        "feature->feature",
        'Feature');

    # Check references between directories.
    push @missing_references, GetMissingReferences(
        $directory_table,
        'Directory_Parent',
        \%directory_map,
        "directory->directory",
        'Directory');

    # Check references from components to directories.
    push @missing_references, GetMissingReferences(
        $component_table,
        'Directory_',
        \%directory_map,
        "component->directory",
        'Component');

    # Check references from components to files (via the .

    # Report the result.
    if (scalar @missing_references > 0)
    {
        $installer::logger::Info->printf("Error: there are %d missing references\n", scalar @missing_references);
        foreach my $reference (@missing_references)
        {
            $installer::logger::Info->printf("    %s : %s -> %s\n",
                $reference->[0],
                $reference->[1],
                $reference->[2]);
        }
        return 0;
    }
    else
    {
        $installer::logger::Info->printf("OK: all references are OK\n");
        return 1;

    }
}




sub Check ($$$$)
{
    my ($source_msi, $target_msi, $variables, $product_name) = @_;

    $installer::logger::Info->printf("checking if source and target releases are compatible\n");
    $installer::logger::Info->increase_indentation();

    my $result = 1;

    # Using &= below to avoid lazy evaluation.  Even if there are errors, all checks shall be run.
    $result &= CheckUpgradeCode($source_msi, $target_msi);
    $result &= CheckProductCode($source_msi, $target_msi);
    $result &= CheckBuildIdCode($source_msi, $target_msi);
    $result &= CheckProductName($source_msi, $target_msi);
    $result &= CheckRemovedFiles($source_msi, $target_msi);
    $result &= CheckNewFiles($source_msi, $target_msi);
    $result &= CheckFeatureSets($source_msi, $target_msi);
    $result &= CheckRemovedComponents($source_msi, $target_msi);
    $result &= CheckAddedComponents($source_msi, $target_msi);
    $result &= CheckComponentValues($source_msi, $target_msi, $variables);
    $result &= CheckFileSequence($source_msi, $target_msi);
    $result &= CheckFileSequenceUnique($source_msi, $target_msi);
    $result &= CheckFileSequenceHoles($source_msi, $target_msi);
    $result &= CheckRegistryItems($source_msi, $target_msi, $product_name);
    $result &= CheckComponentKeyPath($source_msi, $target_msi);
    $result &= CheckAllReferences($target_msi);

    $installer::logger::Info->decrease_indentation();

    if ($result)
    {
        $installer::logger::Info->printf("OK: Source and target releases are compatible.\n");
    }
    else
    {
        $installer::logger::Info->printf("Error: Source and target releases are not compatible.\n");
        $installer::logger::Info->printf("       => Can not create patch.\n");
        $installer::logger::Info->printf("       Did you create the target installation set with 'release=t' ?\n");
    }

    return $result;
}




=head2 FindPcpTemplate ()

    The template.pcp file is part of the Windows SDK.

=cut
sub FindPcpTemplate ()
{
    my $psdk_home = $ENV{'PSDK_HOME'};
    if ( ! defined $psdk_home)
    {
        $installer::logger::Info->printf("Error: the PSDK_HOME environment variable is not set.\n");
        $installer::logger::Info->printf("       did you load the AOO build environment?\n");
        $installer::logger::Info->printf("       you may want to use the --with-psdk-home configure option\n");
        return undef;
    }
    if ( ! -d $psdk_home)
    {
        $installer::logger::Info->printf(
            "Error: the PSDK_HOME environment variable does not point to a valid directory: %s\n",
            $psdk_home);
        return undef;
    }

    my $schema_path = File::Spec->catfile($psdk_home, "Bin", "msitools", "Schemas", "MSI");
    if (  ! -d $schema_path)
    {
        $installer::logger::Info->printf("Error: Can not locate the msi template folder in the Windows SDK\n");
        $installer::logger::Info->printf("       %s\n", $schema_path);
        $installer::logger::Info->printf("       Is the Windows SDK properly installed?\n");
        return undef;
    }

    my $schema_filename = File::Spec->catfile($schema_path, "template.pcp");
    if (  ! -f $schema_filename)
    {
        $installer::logger::Info->printf("Error: Can not locate the pcp template at\n");
        $installer::logger::Info->printf("       %s\n", $schema_filename);
        $installer::logger::Info->printf("       Is the Windows SDK properly installed?\n");
        return undef;
    }

    return $schema_filename;
}




sub SetupPcpPatchMetadataTable ($$$)
{
    my ($pcp, $source_msi, $target_msi) = @_;

    # Determine values for eg product name and source and new version.
    my $source_version = $source_msi->{'version'};
    my $target_version = $target_msi->{'version'};

    my $property_table = $target_msi->GetTable("Property");
    my $display_product_name = $property_table->GetValue("Property", "DEFINEDPRODUCT", "Value");

    # Set table.
    my $table = $pcp->GetTable("PatchMetadata");
    $table->SetRow(
        "Company", "",
        "*Property", "Description",
        "Value", sprintf("Update of %s from %s to %s", $display_product_name, $source_version, $target_version)
        );
    $table->SetRow(
        "Company", "",
        "*Property", "DisplayName",
        "Value", sprintf("Update of %s from %s to %s", $display_product_name, $source_version, $target_version)
        );
    $table->SetRow(
        "Company", "",
        "*Property", "ManufacturerName",
        "Value", $property_table->GetValue("Property", "Manufacturer", "Value"),
        );
    $table->SetRow(
        "Company", "",
        "*Property", "MoreInfoURL",
        "Value", $property_table->GetValue("Property", "ARPURLINFOABOUT", "Value")
        );
    $table->SetRow(
        "Company", "",
        "*Property", "TargetProductName",
        "Value", $property_table->GetValue("Property", "ProductName", "Value")
        );
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time);

    $table->SetRow(
        "Company", "",
        "*Property", "CreationTimeUTC",
        "Value", sprintf("%d/%d/%d %d:%02d", $mon+1,$mday,$year+1900,$hour,$min)
        );
}




sub SetupPropertiesTable ($$)
{
    my ($pcp, $msp_filename) = @_;

    my $table = $pcp->GetTable("Properties");

    $table->SetRow(
        "*Name", "PatchOutputPath",
        "Value", installer::patch::Tools::ToWindowsPath($msp_filename)
        );
    # Request at least Windows installer 2.0.
    # Version 2.0 allows us to omit some values from ImageFamilies table.
    $table->SetRow(
        "*Name", "MinimumRequiredMsiVersion",
        "Value", 200
        );
    # Allow diffs for binary files.
    $table->SetRow(
        "*Name", "IncludeWholeFilesOnly",
        "Value", 0
        );

    my $uuid = installer::windows::msiglobal::create_guid();
    my $uuid_string = "{" . $uuid . "}";
    $table->SetRow(
        "*Name", "PatchGUID",
        "Value", $uuid_string
        );
    $installer::logger::Info->printf("created new PatchGUID %s\n", $uuid_string);

    # Prevent sequence table from being generated.
    $table->SetRow(
        "*Name", "SEQUENCE_DATA_GENERATION_DISABLED",
        "Value", 1);

    # We don't provide file size and hash values.
    # This value is set to make this fact explicit (0 should be the default).
    $table->SetRow(
        "*Name", "TrustMsi",
        "Value", 0);
}




sub SetupImageFamiliesTable ($)
{
    my ($pcp) = @_;

    $pcp->GetTable("ImageFamilies")->SetRow(
        "Family", $ImageFamily,
        "MediaSrcPropName", "",#"MNPSrcPropName",
        "MediaDiskId", "",
        "FileSequenceStart", "",
        "DiskPrompt", "",
        "VolumeLabel", "");
}




sub SetupUpgradedImagesTable ($$)
{
    my ($pcp, $target_msi_path) = @_;

    my $msi_path = installer::patch::Tools::ToWindowsPath($target_msi_path);
    $pcp->GetTable("UpgradedImages")->SetRow(
        "Upgraded", $TargetImageName,
        "MsiPath", $msi_path,
        "PatchMsiPath", "",
        "SymbolPaths", "",
        "Family", $ImageFamily);
}




sub SetupTargetImagesTable ($$)
{
    my ($pcp, $source_msi_path) = @_;

    $pcp->GetTable("TargetImages")->SetRow(
        "Target", $SourceImageName,
        "MsiPath", installer::patch::Tools::ToWindowsPath($source_msi_path),
        "SymbolPaths", "",
        "Upgraded", $TargetImageName,
        "Order", 1,
        "ProductValidateFlags", "",
        "IgnoreMissingSrcFiles", 0);
}




sub SetAdditionalValues ($%)
{
    my ($pcp, %data) = @_;

    while (my ($key,$value) = each(%data))
    {
        $key =~ /^([^\/]+)\/([^:]+):(.+)$/
            || die("invalid key format");
        my ($table_name, $key_column,$key_value) = ($1,$2,$3);
        $value =~ /^([^:]+):(.*)$/
            || die("invalid value format");
        my ($value_column,$value_value) = ($1,$2);

        my $table = $pcp->GetTable($table_name);
        $table->SetRow(
                "*".$key_column, $key_value,
                $value_column, $value_value);
    }
}




sub CreatePcp ($$$$$$%)
{
    my ($source_msi,
        $target_msi,
        $language,
        $context,
        $msp_path,
        $pcp_schema_filename,
        %additional_values) = @_;

    # Create filenames.
    my $pcp_filename = File::Spec->catfile($msp_path, "openoffice.pcp");
    # Create basename to include product name and source and target version.
    # Hard code platform because that is the only platform supported at the moment.
    my $msp_basename = sprintf("%s_%s-%s_Win_x86_patch_%s.msp",
        $context->{'product-name'},
        $source_msi->{'version'},
        $target_msi->{'version'},
        $context->{'language'});
    my $msp_filename = File::Spec->catfile($msp_path, $msp_basename);

    # Setup msp path and filename.
    unlink($pcp_filename) if -f $pcp_filename;
    if ( ! File::Copy::copy($pcp_schema_filename, $pcp_filename))
    {
        $installer::logger::Info->printf("Error: could not create openoffice.pcp as copy of pcp schema\n");
        $installer::logger::Info->printf("       %s\n", $pcp_schema_filename);
        $installer::logger::Info->printf("       %s\n", $pcp_filename);
        return undef;
    }
    my $pcp = installer::patch::Msi->new(
        $pcp_filename,
        $target_msi->{'version'},
        $target_msi->{'is_current_version'},
        $language,
        $context->{'product-name'});

    # Store some values in the pcp for easy reference in the msp creation.
    $pcp->{'msp_filename'} = $msp_filename;

    SetupPcpPatchMetadataTable($pcp, $source_msi, $target_msi);
    SetupPropertiesTable($pcp, $msp_filename);
    SetupImageFamiliesTable($pcp);
    SetupUpgradedImagesTable($pcp, $target_msi->{'filename'});
    SetupTargetImagesTable($pcp, $source_msi->{'filename'});

    SetAdditionalValues(%additional_values);

    $pcp->Commit();

    # Remove the PatchSequence table to avoid MsiMsp error message:
    # "Since MSI 3.0 will block installation of major upgrade patches with
    #  sequencing information, creation of such patches is blocked."
    #$pcp->RemoveTable("PatchSequence");
    # TODO: alternatively add property SEQUENCE_DATA_GENERATION_DISABLED to pcp Properties table.


    $installer::logger::Info->printf("created pcp file at\n");
    $installer::logger::Info->printf("    %s\n", $pcp->{'filename'});

    return $pcp;
}




sub ShowLog ($$$$)
{
    my ($log_path, $log_filename, $log_basename, $new_title) = @_;

    if ( -f $log_filename)
    {
        my $destination_path = File::Spec->catfile($log_path, $log_basename);
        File::Path::make_path($destination_path) if ! -d $destination_path;
        my $command = join(" ",
            "wilogutl.exe",
            "/q",
            "/l", "'".installer::patch::Tools::ToWindowsPath($log_filename)."'",
            "/o", "'".installer::patch::Tools::ToWindowsPath($destination_path)."'");
        printf("running command $command\n");
        my $response = qx($command);
        my @candidates = glob($destination_path . "/Details*");
        foreach my $candidate (@candidates)
        {
            next unless -f $candidate;
            my $new_name = $candidate;
            $new_name =~ s/Details.*$/$log_basename.html/;

            # Rename the top-level HTML file and replace the title.
            open my $in, "<", $candidate;
            open my $out, ">", $new_name;
            while (<$in>)
            {
                if (/^(.*\<title\>)([^<]+)(.*)$/)
                {
                    print $out $1.$new_title.$3;
                }
                else
                {
                    print $out $_;
                }
            }
            close $in;
            close $out;

            my $URL = File::Spec->rel2abs($new_name);
            $URL =~ s/\/cygdrive\/(.)\//$1|\//;
            $URL =~ s/^(.):/$1|/;
            $URL = "file:///". $URL;
            $installer::logger::Info->printf("open %s in your browser to see the log messages\n", $URL);
        }
    }
    else
    {
        $installer::logger::Info->printf("Error: log file not found at %s\n", $log_filename);
    }
}




sub CreateMsp ($)
{
    my ($pcp) = @_;

    # Prepare log files.
    my $log_path = File::Spec->catfile($pcp->{'path'}, "log");
    my $log_basename = "msp";
    my $log_filename = File::Spec->catfile($log_path, $log_basename.".log");
    my $performance_log_basename = "performance";
    my $performance_log_filename = File::Spec->catfile($log_path, $performance_log_basename.".log");
    File::Path::make_path($log_path) if ! -d $log_path;
    unlink($log_filename) if -f $log_filename;
    unlink($performance_log_filename) if -f $performance_log_filename;

    # Create the .msp patch file.
    my $temporary_msimsp_path = File::Spec->catfile($pcp->{'path'}, "tmp");
    if ( ! -d $temporary_msimsp_path)
    {
        File::Path::make_path($temporary_msimsp_path)
            || die ("can not create temporary path ".$temporary_msimsp_path);
    }
    $installer::logger::Info->printf("running msimsp.exe, that will take a while\n");
    my $create_performance_log = 0;
    my $command = join(" ",
        "msimsp.exe",
        "-s", "'".installer::patch::Tools::ToWindowsPath($pcp->{'filename'})."'",
        "-p", "'".installer::patch::Tools::ToWindowsPath($pcp->{'msp_filename'})."'",
        "-l", "'".installer::patch::Tools::ToWindowsPath($log_filename)."'",
        "-f", "'".installer::patch::Tools::ToWindowsPath($temporary_msimsp_path)."'");
    if ($create_performance_log)
    {
        $command .= " -lp " . MsiTools::ToEscapedWindowsPath($performance_log_filename);
    }
    $installer::logger::Info->printf("running command %s\n", $command);
    my $response = qx($command);
    $installer::logger::Info->printf("response of msimsp is %s\n", $response);
    if ( ! -d $temporary_msimsp_path)
    {
        die("msimsp failed and deleted temporary path ".$temporary_msimsp_path);
    }

    # Show the log file that was created by the msimsp.exe command.
    ShowLog($log_path, $log_filename, $log_basename, "msp creation");
    if ($create_performance_log)
    {
        ShowLog($log_path, $performance_log_filename, $performance_log_basename, "msp creation perf");
    }
}


sub ProvideMsis ($$$)
{
    my ($context, $variables, $language) = @_;

    # 2a. Provide .msi and .cab files and unpack .cab for the source release.
    $installer::logger::Info->printf("locating source package (%s)\n", $context->{'source-version'});
    $installer::logger::Info->increase_indentation();
    if ( ! installer::patch::InstallationSet::ProvideUnpackedCab(
	       $context->{'source-version'},
	       0,
	       $language,
	       "msi",
	       $context->{'product-name'}))
    {
        die "could not provide unpacked .cab file";
    }
    my $source_msi = installer::patch::Msi->FindAndCreate(
        $context->{'source-version'},
        0,
        $language,
        $context->{'product-name'});
    die unless defined $source_msi;
    die unless $source_msi->IsValid();
    $installer::logger::Info->decrease_indentation();

    # 2b. Provide .msi and .cab files and unpacked .cab for the target release.
    $installer::logger::Info->printf("locating target package (%s)\n", $context->{'target-version'});
    $installer::logger::Info->increase_indentation();
    if ( ! installer::patch::InstallationSet::ProvideUnpackedCab(
               $context->{'target-version'},
               1,
               $language,
               "msi",
               $context->{'product-name'}))
    {
        die;
    }
    my $target_msi = installer::patch::Msi->FindAndCreate(
        $context->{'target-version'},
        0,
        $language,
        $context->{'product-name'});
    die unless defined $target_msi;
    die unless $target_msi->IsValid();
    $installer::logger::Info->decrease_indentation();

    return ($source_msi, $target_msi);
}




=head CreatePatch($context, $variables)

    Create MSP patch files for all relevant languages.
    The different steps are:
    1. Determine the set of languages for which both the source and target installation sets are present.
    Per language:
        2. Unpack CAB files (for source and target).
        3. Check if source and target releases are compatible.
        4. Create the PCP driver file.
        5. Create the MSP patch file.

=cut
sub CreatePatch ($$)
{
    my ($context, $variables) = @_;

    $installer::logger::Info->printf("patch will update product %s from %s to %s\n",
        $context->{'product-name'},
        $context->{'source-version'},
        $context->{'target-version'});

    # Locate the Pcp schema file early on to report any errors before the lengthy operations that follow.
    my $pcp_schema_filename = FindPcpTemplate();
    if ( ! defined $pcp_schema_filename)
    {
        exit(1);
    }

    my $release_data = installer::patch::ReleasesList::Instance()
        ->{$context->{'source-version'}}
        ->{$context->{'package-format'}};

    # 1. Determine the set of languages for which we can create patches.
    my $language = $context->{'language'};
    my %no_ms_lang_locale_map = map {$_=>1} @installer::globals::noMSLocaleLangs;
    if (defined $no_ms_lang_locale_map{$language})
    {
        $language = "en-US_".$language;
    }

    if ( ! IsLanguageValid($context, $release_data, $language))
    {
        $installer::logger::Info->printf("can not create patch for language '%s'\n", $language);
    }
    else
    {
        $installer::logger::Info->printf("processing language '%s'\n", $language);
        $installer::logger::Info->increase_indentation();

        my ($source_msi, $target_msi) = ProvideMsis($context, $variables, $language);

        # Trigger reading of tables.
        foreach my $table_name (("File", "Component", "Registry"))
        {
            $source_msi->GetTable($table_name);
            $target_msi->GetTable($table_name);
            $installer::logger::Info->printf("read %s table (source and target\n", $table_name);
        }

        # 3. Check if the source and target msis fullfil all necessary requirements.
        if ( ! Check($source_msi, $target_msi, $variables, $context->{'product-name'}))
        {
            exit(1);
        }

        # Provide the base path for creating .pcp and .mcp file.
        my $msp_path = File::Spec->catfile(
            $context->{'output-path'},
            $context->{'product-name'},
            "msp",
            sprintf("%s_%s",
                installer::patch::Version::ArrayToDirectoryName(
                    installer::patch::Version::StringToNumberArray(
                        $source_msi->{'version'})),
                installer::patch::Version::ArrayToDirectoryName(
                    installer::patch::Version::StringToNumberArray(
                        $target_msi->{'version'}))),
            $language
            );
        File::Path::make_path($msp_path) unless -d $msp_path;

        # 4. Create the .pcp file that drives the msimsp.exe command.
        my $pcp = CreatePcp(
            $source_msi,
            $target_msi,
            $language,
            $context,
            $msp_path,
            $pcp_schema_filename,
            "Properties/Name:DontRemoveTempFolderWhenFinished" => "Value:1");

        # 5. Finally create the msp.
        CreateMsp($pcp);

        $installer::logger::Info->decrease_indentation();
    }
}




sub CheckPatchCompatability ($$)
{
    my ($context, $variables) = @_;

    $installer::logger::Info->printf("patch will update product %s from %s to %s\n",
        $context->{'product-name'},
        $context->{'source-version'},
        $context->{'target-version'});

    my $release_data = installer::patch::ReleasesList::Instance()
        ->{$context->{'source-version'}}
        ->{$context->{'package-format'}};

    # 1. Determine the set of languages for which we can create patches.
    my $language = $context->{'language'};
    my %no_ms_lang_locale_map = map {$_=>1} @installer::globals::noMSLocaleLangs;
    if (defined $no_ms_lang_locale_map{$language})
    {
        $language = "en-US_".$language;
    }

    if ( ! IsLanguageValid($context, $release_data, $language))
    {
        $installer::logger::Info->printf("can not create patch for language '%s'\n", $language);
    }
    else
    {
        $installer::logger::Info->printf("processing language '%s'\n", $language);
        $installer::logger::Info->increase_indentation();

        my ($source_msi, $target_msi) = ProvideMsis($context, $variables, $language);

        # Trigger reading of tables.
        foreach my $table_name (("File", "Component", "Registry"))
        {
            $source_msi->GetTable($table_name);
            $target_msi->GetTable($table_name);
            $installer::logger::Info->printf("read %s table (source and target\n", $table_name);
        }

        # 3. Check if the source and target msis fulfill all necessary requirements.
        if ( ! Check($source_msi, $target_msi, $variables, $context->{'product-name'}))
        {
            exit(1);
        }
    }
}




=cut ApplyPatch ($context, $variables)

    This is for testing only.
    The patch is applied and (extensive) log information is created and transformed into HTML format.

=cut
sub ApplyPatch ($$)
{
    my ($context, $variables) = @_;

    $installer::logger::Info->printf("will apply patches that update product %s from %s to %s\n",
        $context->{'product-name'},
        $context->{'source-version'},
        $context->{'target-version'});

    my $source_version_dirname = installer::patch::Version::ArrayToDirectoryName(
      installer::patch::Version::StringToNumberArray(
          $context->{'source-version'}));
    my $target_version_dirname = installer::patch::Version::ArrayToDirectoryName(
      installer::patch::Version::StringToNumberArray(
          $context->{'target-version'}));

    my $language = $context->{'language'};
    my %no_ms_lang_locale_map = map {$_=>1} @installer::globals::noMSLocaleLangs;
    if (defined $no_ms_lang_locale_map{$language})
    {
        $language = "en-US_".$language;
    }

    my $msp_filename = File::Spec->catfile(
        $context->{'output-path'},
        $context->{'product-name'},
        "msp",
        $source_version_dirname . "_" . $target_version_dirname,
        $language,
        "openoffice.msp");
    if ( ! -f $msp_filename)
    {
        $installer::logger::Info->printf("%s does not point to a valid file\n", $msp_filename);
        next;
    }

    my $log_path = File::Spec->catfile(dirname($msp_filename), "log");
    my $log_basename = "apply-msp";
    my $log_filename = File::Spec->catfile($log_path, $log_basename.".log");

    my $command = join(" ",
        "msiexec.exe",
        "/update", "'".installer::patch::Tools::ToWindowsPath($msp_filename)."'",
        "/L*xv!", "'".installer::patch::Tools::ToWindowsPath($log_filename)."'",
        "REINSTALL=ALL",
#            "REINSTALLMODE=vomus",
        "REINSTALLMODE=omus",
        "MSIENFORCEUPGRADECOMPONENTRULES=1");

    printf("executing command %s\n", $command);
    my $response = qx($command);
    Encode::from_to($response, "UTF16LE", "UTF8");
    printf("response was '%s'\n", $response);

    ShowLog($log_path, $log_filename, $log_basename, "msp application");
}




=head2 DownloadFile ($url)

    A simpler version of InstallationSet::Download().  It is simple because it is used to
    setup the $release_data structure that is used by InstallationSet::Download().

=cut
sub DownloadFile ($)
{
    my ($url) = shift;

    my $agent = LWP::UserAgent->new();
    $agent->timeout(120);
    $agent->show_progress(0);

    my $file_content = "";
    my $last_was_redirect = 0;
    my $bytes_read = 0;
    $agent->add_handler('response_redirect'
        => sub{
            $last_was_redirect = 1;
            return;
        });
    $agent->add_handler('response_data'
        => sub{
            if ($last_was_redirect)
            {
                $last_was_redirect = 0;
                # Throw away the data we got so far.
		$file_content = "";
            }
            my($response,$agent,$h,$data)=@_;
	    $file_content .= $data;
        });
    $agent->get($url);

    return $file_content;
}




sub CreateReleaseItem ($$$)
{
    my ($language, $exe_filename, $msi) = @_;

    die "can not open installation set at ".$exe_filename unless -f $exe_filename;

    open my $in, "<", $exe_filename;
    my $sha256_checksum = new Digest("SHA-256")->addfile($in)->hexdigest();
    close $in;

    my $filesize = -s $exe_filename;

    # Get the product code property from the msi and strip the enclosing braces.
    my $product_code = $msi->GetTable("Property")->GetValue("Property", "ProductCode", "Value");
    $product_code =~ s/(^{|}$)//g;
    my $upgrade_code = $msi->GetTable("Property")->GetValue("Property", "UpgradeCode", "Value");
    $upgrade_code =~ s/(^{|}$)//g;
    my $build_id = $msi->GetTable("Property")->GetValue("Property", "PRODUCTBUILDID", "Value");

    return {
        'language' => $language,
        'checksum-type' => "sha256",
        'checksum-value' => $sha256_checksum,
        'file-size' => $filesize,
        'product-code' => $product_code,
        'upgrade-code' => $upgrade_code,
        'build-id' => $build_id
    };
}




sub GetReleaseItemForCurrentBuild ($$$)
{
    my ($context, $language, $exe_basename) = @_;

    # Target version is the current version.
    # Search instsetoo_native for the installation set.
    my $filename = File::Spec->catfile(
        $context->{'output-path'},
        $context->{'product-name'},
        $context->{'package-format'},
        "install",
        $language."_download",
        $exe_basename);

    printf("        current : %s\n", $filename);
    if ( ! -f $filename)
    {
        printf("ERROR: can not find %s\n", $filename);
        return undef;
    }
    else
    {
        my $msi = installer::patch::Msi->FindAndCreate(
            $context->{'target-version'},
            1,
            $language,
            $context->{'product-name'});
        return CreateReleaseItem($language, $filename, $msi);
    }
}



sub GetReleaseItemForOldBuild ($$$$)
{
    my ($context, $language, $exe_basename, $url_template) = @_;

    # Use ext_sources/ as local cache for archive.apache.org
    # and search these for the installation set.

    my $version = $context->{'target-version'};
    my $package_format =  $context->{'package-format'};
    my $releases_list = installer::patch::ReleasesList::Instance();

    my $url = $url_template;
    $url =~ s/%L/$language/g;
    $releases_list->{$version}->{$package_format}->{$language}->{'URL'} = $url;

    if ( ! installer::patch::InstallationSet::ProvideUnpackedExe(
               $version,
               0,
               $language,
               $package_format,
               $context->{'product-name'}))
    {
        # Can not provide unpacked EXE.
        return undef;
    }
    else
    {
        my $exe_filename = File::Spec->catfile(
            $ENV{'TARFILE_LOCATION'},
            $exe_basename);
        my $msi = installer::patch::Msi->FindAndCreate(
            $version,
            0,
            $language,
            $context->{'product-name'});
        return CreateReleaseItem($language, $exe_filename, $msi);
    }
}




sub UpdateReleasesXML($$)
{
    my ($context, $variables) = @_;

    my $releases_list = installer::patch::ReleasesList::Instance();
    my $output_filename = File::Spec->catfile(
        $context->{'output-path'},
        "misc",
        "releases.xml");

    my $target_version = $context->{'target-version'};
    my %version_hash = map {$_=>1} @{$releases_list->{'releases'}};
    my $item_hash = undef;
    if ( ! defined $version_hash{$context->{'target-version'}})
    {
        # Target version is not yet present.  Add it and print message that asks caller to check order.
        push @{$releases_list->{'releases'}}, $target_version;
        printf("adding data for new version %s to list of released versions.\n", $target_version);
        printf("please check order of releases in $output_filename\n");
        $item_hash = {};
    }
    else
    {
        printf("adding data for existing version %s to releases.xml\n", $target_version);
        $item_hash = $releases_list->{$target_version}->{$context->{'package-format'}};
    }
    $releases_list->{$target_version} = {$context->{'package-format'} => $item_hash};

    my @languages = GetLanguages();
    my %language_items = ();
    foreach my $language (@languages)
    {
        # There are three different sources where to find the downloadable installation sets.
        # 1. archive.apache.org for previously released versions.
        # 2. A local cache or repository directory that conceptually is a local copy of archive.apache.org
        # 3. The downloadable installation sets built in instsetoo_native/.

        my $exe_basename = sprintf(
            "%s_%s_Win_x86_install_%s.exe",
            $context->{'product-name'},
            $target_version,
            $language);
        my $url_template = sprintf(
            "http://archive.apache.org/dist/openoffice/%s/binaries/%%L/%s_%s_Win_x86_install_%%L.exe",
            $target_version,
            $context->{'product-name'},
            $target_version);

        my $item = undef;
        if ($target_version eq $variables->{PRODUCTVERSION})
        {
            $item = GetReleaseItemForCurrentBuild($context, $language, $exe_basename);
        }
        else
        {
            $item = GetReleaseItemForOldBuild($context, $language, $exe_basename, $url_template);
        }

        next unless defined $item;

        $language_items{$language} = $item;
        $item_hash->{$language} = $item;
        $item_hash->{'upgrade-code'} = $item->{'upgrade-code'};
        $item_hash->{'build-id'} = $item->{'build-id'};
        $item_hash->{'url-template'} = $url_template;
    }

    my @valid_languages = sort keys %language_items;
    $item_hash->{'languages'} = \@valid_languages;

    $releases_list->Write($output_filename);

    printf("\n\n");
    printf("please copy '%s' to main/instsetoo_native/data\n", $output_filename);
    printf("and check in the modified file to the version control system\n");
}




sub main ()
{
    my $context = ProcessCommandline();
#    installer::logger::starttime();
#    $installer::logger::Global->add_timestamp("starting logging");
    installer::logger::SetupSimpleLogging(undef);

    die "ERROR: list file is not defined, please use --lst-file option"
        unless defined $context->{'lst-file'};
    die "ERROR: product name is not defined, please use --product-name option"
        unless defined $context->{'product-name'};
    die sprintf("ERROR: package format %s is not supported", $context->{'package-format'})
        unless defined $context->{'package-format'} ne "msi";

    my ($variables, undef, undef) = installer::ziplist::read_openoffice_lst_file(
        $context->{'lst-file'},
        $context->{'product-name'},
        undef);
    DetermineVersions($context, $variables);

    if ($context->{'command'} =~ /create|check/)
    {
        my $filename = File::Spec->catfile(
            $context->{'output-path'},
            $context->{'product-name'},
            "msp",
            $context->{'source-version-dash'} . "_" . $context->{'target-version-dash'},
            $context->{'language'},
            "log",
            "patch-creation.log");
        my $dirname = dirname($filename);
        File::Path::make_path($dirname) unless -d $dirname;
        printf("directing output to $filename\n");

        $installer::logger::Lang->set_filename($filename);
        $installer::logger::Lang->copy_lines_from($installer::logger::Global);
        $installer::logger::Lang->set_forward(undef);
        $installer::logger::Info->set_forward($installer::logger::Lang);
    }

    if ($context->{'command'} eq "create")
    {
        CreatePatch($context, $variables);
    }
    elsif ($context->{'command'} eq "apply")
    {
        ApplyPatch($context, $variables);
    }
    elsif ($context->{'command'} eq "update-releases-xml")
    {
        UpdateReleasesXML($context, $variables);
    }
    elsif ($context->{'command'} eq "check")
    {
        CheckPatchCompatability($context, $variables);
    }
}


main();
