#!/usr/bin/perl -w

use FindBin;
use lib "$FindBin::Bin/../perl_lib";

######################################################################
#
#
######################################################################

=pod

=head1 NAME

B<remove_citation_caches> - Remove entries from the citationcache.

=head1 SYNOPSIS

B<remove_citation_caches> I<repository_id> [B<options>]

=head1 DESCRIPTION

This script will remove cached citations based on datasetid, citation-style or object id.
By default it will only remove citations with a null 'context', which was added in 3.4.7.
Other citations would naturally get regenrated over time, but these 'null-context citations
would never get updated.

=head1 ARGUMENTS

=over 8

=item B<repository_id>

The ID of the eprint repository to use.

=back

=head1 OPTIONS

=over 8

=item B<--help>

Print a brief help message and exit.

=item B<--man>

Print the full manual page and then exit.

=item B<--quiet>

Be vewwy vewwy quiet. This option will suppress all output unless an error occurs.

=item B<--verbose>

Explain in detail what is going on.
May be repeated for greater effect.

=item B<--version>

Output version information and exit.

=item B<--datasetid>

Only remove null-context caches for a specific dataset.

=item B<--objectid>

Remove null-context caches for a specific item (datasetid must also be declared).

=item B<--style>

Remove null-context citations for a specific style. Should be combined with a datasetid.

=item B<--all-matching>

Remove all citations that match other options, not just the null-context ones.

=back

=cut

use EPrints;

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

my $version = 0;
my $verbose = 0;
my $quiet = 0;
my $help = 0;
my $man = 0;

my $all_matching = 0;
# These use 'our' as they are symbolically-referenced below $$opt --> $datasetid
our $datasetid;
our $style;
our $objectid;

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

GetOptions(
	'help|?' => \$help,
	'man' => \$man,
	'version' => \$version,
	'verbose+' => \$verbose,
	'silent' => \$quiet,
	'quiet' => \$quiet,
	'all-matching' => \$all_matching,
	'datasetid=s' => \$datasetid,
	'objectid=s' => \$objectid,
	'style=s' => \$style,
) || pod2usage( 2 );

EPrints::Utils::cmd_version( "remove_citation_caches" ) if $version;
pod2usage( 1 ) if $help;
pod2usage( -exitstatus => 0, -verbose => 2 ) if $man;
pod2usage( 2 ) if( scalar @ARGV != 1 );

my $noise = 1;
$noise = 0 if( $quiet );
$noise = 1+$verbose if( $verbose );

# Set STDOUT to auto flush (without needing a \n)
$|=1;

my $repoid = $ARGV[0];
my $session = new EPrints::Session( 1 , $repoid , $noise );
if( !defined $session )
{
	print STDERR "Failed to load repository: $repoid\n";
	exit 1;
}

if( !defined $session->config( "citation_caching", "enabled" ) || !$session->config( "citation_caching", "enabled" ) )
{
	print STDERR "Citation caching not enabled for $repoid\n";
	$session->terminate();
	exit 1;
}

if( defined $objectid && !defined $datasetid )
{
	print STDERR "To clear null-context citations for a specific object, please provide the datasetid option as well as the objectid.\n";
	$session->terminate();
	exit 1;
}

if( $all_matching && !defined $datasetid && !defined $style )
{
	print STDERR "Please specify a datasetid or style when using the '--all-matching' option\n";
	$session->terminate();
	exit 1;
}

my $ds = $session->dataset( "citationcache" );
my $searchexp = $ds->prepare_search();

my $summary = "Looking for";
if ( !$all_matching )
{
	$summary .= " null-context citations";
	$searchexp->add_field(
		fields => [
			$ds->field('context')
		],
		value => undef,
		match => "EX",
	);
}
else
{
	$summary .= " all citations";
}
$summary .= " that match:\n";

foreach my $opt ( qw/ datasetid objectid style / )
{
	no strict 'refs';

	if( defined $$opt )
	{
		$summary .= "\t$opt:\t$$opt\n";

		$searchexp->add_field(
			fields => [
				$ds->field( $opt )
			],
			value => $$opt,
			match => "EQ",
		);
	}
}

print $summary if $noise;

my $list = $searchexp->perform_search;
print "Caches found:\t", $list->count(), "\n" if $noise;

my $info = { caches_cleared => 0 };
$list->map( sub{
	my( $session, $ds, $cache, $info ) = @_;

	my $id = $cache->get_id;
	my $rc = $cache->remove;
	$info->{caches_cleared}++ if $rc;

	if( $noise > 1 )
	{
		print "Cache $id ", ( $rc ? "removed" : "removal failed" ), ".\n";
	}
}, $info );

print "Caches removed:\t", $info->{caches_cleared}, "\n" if $noise;

$session->terminate();
exit;

