#!/usr/bin/env perl

# Copyright (c) 2013-2020 by Martin Becker, Blaubeuren.
# This script is free software; you can redistribute it and/or modify it
# under the terms of the Artistic License 2.0 (see the LICENSE file).

use strict;
use warnings;
use version 0.77;
use Module::Version qw(get_version);
use Module::CoreList;

my $in_core      = $Module::CoreList::version{$]} || {};
my $MAKEFILE_PL  = 'Makefile.PL';
my $MAKEFILE_TMP = 'Makefile.TMP';
my $OVERRIDE     = 'OVERRIDE';
my $THIS_YEAR    = this_year();

my $changes   = 0;
my @core_mods = ();
my %override  = ();

if (open my $of, '<', $OVERRIDE) {
    while (<$of>) {
        if (/^([\w:]+)\s+([\d._]+)\s*\z/) {
            $override{$1} = $2;
        }
    }
    close $of;
}

open my $mf, '<', $MAKEFILE_PL  or die "$MAKEFILE_PL: cannot open: $!\n";
open my $tf, '>', $MAKEFILE_TMP or die "$MAKEFILE_TMP: cannot create: $!\n";
while (<$mf>) {
    s/^(# Copyright \(c\) 2013-)\d{4}\b/$1$THIS_YEAR/;
    s/^((?:requires|recommends)\s+'([\w\:]+)'\s*=>\s*')([\d._]+)(?=';)/$1 .
        _get_version($2, $3)/e;
    print $tf $_ or die "$MAKEFILE_TMP: cannot write: $!\n";
}
close $tf or die "$MAKEFILE_TMP: cannot write+close: $!\n";
close $mf;

foreach my $module (@core_mods) {
    warn "WARNING: $module $in_core->{$module} is from core\n";
}
if ($changes) {
    die "To commit these changes, move $MAKEFILE_TMP to $MAKEFILE_PL\n";
}

unlink $MAKEFILE_TMP or die "$MAKEFILE_TMP: cannot remove: $!\n";

sub this_year { (localtime)[5] + 1900 }

sub _get_version {
    my ($module, $old_version) = @_;
    my $version =
        exists($override{$module})? $override{$module}:
        get_version($module);
    if (!defined $version) {
        warn "$module: not present, keeping version $old_version\n";
        return $old_version;
    }
    my $version_obj = version->parse($version);
    my $cmp = version->parse($old_version) <=> $version_obj;
    if ($cmp > 0) {
        warn "$module: too old, keeping version $old_version\n";
        return $old_version;
    }
    return $old_version if !$cmp;
    if (exists $in_core->{$module}) {
        my $ccmp = version->parse($in_core->{$module}) <=> $version_obj;
        if (!$ccmp) {
            push @core_mods, $module;
        }
    }
    warn "$module: upgrading to version $version from $old_version\n";
    ++$changes;
    if ('v' eq substr $version, 0, 1) {
        return version->parse($version)->numify;
    }
    return $version;
}

__END__
