#!/usr/bin/env perl
#***********************************************************************
# This file is part of OpenMolcas.                                     *
#                                                                      *
# OpenMolcas is free software; you can redistribute it and/or modify   *
# it under the terms of the GNU Lesser General Public License, v. 2.1. *
# OpenMolcas is distributed in the hope that it will be useful, but it *
# is provided "as is" and without any express or implied warranties.   *
# For more details see the full text of the license in the file        *
# LICENSE or in <http://www.gnu.org/licenses/>.                        *
#                                                                      *
# Copyright (C) 2015, Steven Vancoillie                                *
#***********************************************************************
#
# makepatch
#
# Script that creates a self-applying patch file for Molcas.
# It takes two tags as argument, from which version to which
# version it needs to make a patch. The result is a file called
# molcaspatch-$from_version.plx, a perl script that can apply the
# patch.
#
# Steven Vancoillie, May 2015

use File::Basename;

my $MOLCAS_DRIVER;
$MOLCAS_DRIVER = $ENV{"MOLCAS_DRIVER"} or $MOLCAS_DRIVER = "molcas";
my $DRIVER_base = basename($MOLCAS_DRIVER);

sub usage {
        print <<"EOF";
Create a self-applying patch script for Molcas that takes
it from one version to another. If no second version is
given the patch will upgrade Molcas to the latest stable
version.

Usage:

  $DRIVER_base makepatch from <to>"
      from: version tag that indicates the base of the patch
            (e.g. v8.0.14-02-17)
      <to>: version tag that indicates the target of the patch
            this is optional, if not given then the latest stable
            version is taken instead
EOF
}

my $MOLCAS=$ENV{"MOLCAS"};
die "MOLCAS not set, use $DRIVER_base makepatch\n" unless ($MOLCAS);

# if this is a git repo, sanity check if git exists,
# otherwise print a warning.
my $git_exists = 0;
foreach my $path (split /:/, $ENV{'PATH'}) {
    if ( -f "$path/git" && -x _ ) {
        $git_exists = 1;
        last;
    }
}
if ( not -e "$MOLCAS/.git" or not $git_exists) {
    print "Error: git not available or not a git repo\n";
    exit 1;
}

# the from and to versions are the two command line arguments
my $from_version = shift @ARGV;
my $to_version   = shift @ARGV;

unless ($from_version) {
        usage();
        exit 1;
}

unless ($to_version) {
        chomp ($to_version = `git tag -l --points-at origin/master v*`);
}

chdir $MOLCAS or die "Error: could not chdir to $MOLCAS";
system("git", "fetch");
system("git", "fetch", "--tags");

my $top_script = <<'EOF_TOP';
#!/usr/bin/env perl
my $from_version = ::FROM::;
my $to_version   = ::TO::;

print "updating Molcas 8.0 from patch level $from_version to $to_version\n";

# check if in root of Molcas tree
unless (-e .molcashome) {
        print "This is not a Molcas root directory!\n";
        exit 1;
}

# get the version
my $versionfile = '.molcasversion';
open VERSION, '<', $versionfile or die "no version file!";
my $line = <VERSION>;
$line =~ m/Molcas version 8\.0 patch level (\d\d-\d\d-\d\d)/;
my $patchlevel = $1;

# check if version is correct
if ($patchlevel != $from_version) {
        print "This is the wrong Molcas version,\n";
        print "expecting version 8.0 patch level $from_version.\n";
        print "but this is patch level $patchlevel.\n";
        exit 1;
}
close VERSION;

# try to apply patch
my $patchfile = '.molcas.patch';

if (-e $patchfile) {
        print "existing patch file!\n";
        print "please remove .molcas.patch\n";
        exit 1;
}

open PATCH, '>', $patchfile;
print PATCH <<'EOF_PATCH';
EOF_TOP

my $bottom_script = <<'EOF_BOTTOM';
EOF_PATCH

close PATCH;

system ("patch -p1 -i .molcas.patch");

unlink $patchfile;

my $versionfile = '.molcasversion';
open VERSION, '<', $versionfile or die "no version file!";
my $versionstring = "Molcas version 8.0 patch level $to_version\n";
print VERSION $versionstring;
close VERSION;

print "DONE!\n";
print "please rerun configure and make...";

exit 0;
EOF_BOTTOM

my $middle_script = `git diff $from_version $to_version`;

# fill in the version numbers
$top_script =~ s/::FROM::/$from_version/;
$top_script =~ s/::TO::/$to_version/;

#my $applyfile = "molcaspatch-$from_version.plx";
#open APPLY, '>', $applyfile or die "cannot open output file!";
#print APPLY $top_script, $middle_script, $bottom_script;
#close APPLY;

print $top_script, $middle_script, $bottom_script;
