#!/usr/bin/perl -w

use strict;
use File::Find;
use Storable;
use Getopt::Std;
use Data::Dumper;

my %first_hash = ();
my %second_hash = ();
my %opts = ();
my $file = "/tmp/first_hash";

sub search_first {
	if (-f $_) {
		my $size = -s $_;
		print ".";
		my $key = $File::Find::name =~ s/$ARGV[0]//r;
		$first_hash{ $key } = $size;
	}
}

sub search_second {
	if (-f $_) {
		my $size = -s $_;
		print "*";
		my $key = $File::Find::name =~ s/$ARGV[1]//r;
		$second_hash{ $key } = $size;
	}
}

sub print_hashes {
	print("Files in $ARGV[1] that differ from files in $ARGV[0]:\n");
    foreach my $key (keys %second_hash) {
		if (exists($first_hash{ $key }) && ($first_hash{ $key } != $second_hash{ $key })) {
			print("$key $first_hash{ $key } != $second_hash{ $key }\n");
			print "Delete $ARGV[1]/$key? (Y)";
			chomp(my $answer = <STDIN>);
			if (uc($answer) ne 'N') {
				system("rm \"$ARGV[1]/$key\"");
			}
		}
    }

	if ($opts{ 'd' } && $opts{ 'd' } eq 1) {
		print("Files in $ARGV[1] that have a duplicate in $ARGV[0]:\n");
		foreach my $key (keys %second_hash) {
			if (exists($first_hash{ $key })) {
				print "$key";
			}
		}
	}

	print("\n");
}

getopts('d', \%opts);
if (-f $file) {
	%first_hash = %{ retrieve($file) };
}
else {
	find(\&search_first, $ARGV[0]);
	print("\n");
	store(\%first_hash, $file);
}
find(\&search_second, $ARGV[1]);
print("\n");
print_hashes();

=head1 NAME

size_dir_diff - find differences between two directories

=head1 DESCRIPTION

A script that finds differences between two directories.

Two directories are compared taking the size of each file.
Files in the second argument are treated as a subset of the first.

=head1 SYNOPSIS

  $ size_dir_diff.pl -d /usr/src/BPi/device-tree /usr/src/BPi/device-tree.copy
  .
  *
  Files in /usr/src/BPi/device-tree.copy that differ from files in /usr/src/BPi/device-tree:
  Files in /usr/src/BPi/device-tree.copy that have a duplicate in /usr/src/BPi/device-tree:
  /sun7i-a20-bananapi.dtb

=head1 AUTHOR

Jonas Jensen

=head1 LICENSE

gpl_2

=head1 INSTALLATION

Using C<cpan>:

    $ cpan App::size_dir_diff

Manual install:

    $ perl Makefile.PL
    $ make
    $ make install

=cut
