#!/usr/bin/perl -w

use File::Slurp;
use XML::LibXML;
use XML::Twig;
use Digest::MD5;

use strict;
use Getopt::Long;
use Pod::Usage;

my $dir = "/opt/eprints3";
my $ignore_list = "/home/nagios/epm_ignore.list";

Getopt::Long::Configure("permute");

GetOptions(
        'ignore_list=s' => \$ignore_list,
        'eprints_path=s' => \$dir,
);

my @epm_dirs = glob( $dir . '/lib/epm/*' );

my @ignore_files = ();
if ( $ignore_list && -f $ignore_list )
{
	@ignore_files = read_file( $ignore_list, chomp => 1);
}

my $warnings = 0;
my $msg = "";
foreach my $epm_dir ( @epm_dirs )
{
	my @epm_dir_bits = split( '/', $epm_dir );
	my $epmi_file = $epm_dir . '/' . $epm_dir_bits[$#epm_dir_bits] . '.epmi';
	unless ( -f $epmi_file )
	{
		if ( ! grep( /^$epmi_file$/, @ignore_files ) )
		{
			$msg .= "EPMI file $epmi_file does not exist.\n";
        	        $warnings++;
		}
		next;
	}
	my $epmi = XML::LibXML->load_xml(location => $epmi_file);
	my $xpc = XML::LibXML::XPathContext->new();
	$xpc->registerNs( epd => 'http://eprints.org/ep2/data/2.0' );

	my @file_nodes = $xpc->findnodes('//epd:documents/epd:document[1]/epd:files/epd:file', $epmi );
	foreach my $file_node ( @file_nodes )
	{
		my $twig = XML::Twig->new();
		my $file = $twig->parse( $file_node )->simplify();
		next if $file->{filename} =~ m!^epm/!;
		my $filename = "$dir/lib/" . $file->{filename};
		next if grep( /^$filename$/, @ignore_files );
		if ( $file->{hash_type} eq "MD5" )
		{
			if ( -f $filename )
			{
				open (my $fh, '<', $filename);
				binmode($fh);
 				my $md5 = Digest::MD5->new;
				while (<$fh>) 
				{
					$md5->add($_);
				}
				close($fh);
				if ( $file->{hash} ne $md5->hexdigest )
				{	
					$msg .= $file->{hash_type} . " checksum mismatch for $filename from $epmi_file.\n";
					$warnings++;
				}
			}
			else
			{
				$msg .= "Missing $filename from $epmi_file.\n";
				$warnings++;
			}	
		}
		else
		{
			$msg .= "Unrecognised checksum type (".$file->{hash_type}.") for $filename in $epmi_file.\n";
			$warnings++;
		}

	}	
}

if ( $warnings gt 0 )
{
	print "WARNING: $warnings EPM file(s) reported checksum issues.\n";
	print $msg;
	exit 1;
}

print "OK: No EPM file(s) reported checksum issues.\n";
exit 0;
