#!/usr/bin/perl -w

use strict;
use File::Spec       ();
use PPI::Document    ();
use File::Find::Rule ();

use vars qw{$VERSION};
BEGIN {
	$VERSION = '0.06';
}

my $command = shift @ARGV;
unless ( $command and $command eq 'change' ) {
	die "The 'change' command is the only commanded implemented at present";
}

my $from = shift @ARGV;
unless ( $from and $from =~ /^[\d\._]+$/ ) {
	die "From is not a number";
}
my $to = shift @ARGV;
unless ( $to and $to =~ /^[\d\._]+$/ ) {
	die "To is not a number";
}

$from = "'$from'";
$to   = "'$to'";

# Find all modules and scripts below the current directory
my @files = File::Find::Rule->file
                            ->name('*.pm', '*.pl', '*.t')
                            ->in( File::Spec->curdir );
print  "Found " . scalar(@files) . " file(s)\n";

my $count = 0;
foreach my $file ( @files ) {
	print "$file...";
	if ( ! -w $file ) {
		print " no write permission\n";
		next;
	}
	my $rv = changefile( $file, $from, $to );
	if ( $rv ) {
		print " updated\n";
		$count++;
	} else {
		print " skipped\n";
	}
}

print "Done. Updated " . scalar($count) . " file(s)\n";
exit(0);

sub changefile {
	my ($file, $from, $to) = @_;
	my $Document = PPI::Document->new( $file ) or die "PPI::Document failed";

	# Does the document contain a simple version number
	my $elements = $Document->find( sub {
		$_[1]->isa('PPI::Token::Quote')          or return '';
		$_[1]->content eq $from                  or return '';
		my $equals = $_[1]->sprevious_sibling    or return '';
		$equals->isa('PPI::Token::Operator')     or return '';
		$equals->content eq '='                  or return '';
		my $version = $equals->sprevious_sibling or return '';
		$version->isa('PPI::Token::Symbol')      or return '';
		$version->content eq '$VERSION'          or return '';
		1;
		} );
	return '' unless $elements;
	if ( @$elements > 1 ) {
		die "$file contains more than one $VERSION = '$from';";
	}
	my $element = $elements->[0];
	$element->{content} = $to;

	# Save the updated version
	$Document->save( $file ) or die "PPI::Document save failed";
	1;
}

1;
