#!/usr/bin/perl -w

######################################################################
#                  EPrints metadata to RePEC ReDIF              
#   Converts metadata of an EPrints server into RePEc ReDIF format   
#   Author: Volker Schallehn, Munich University Library, Germany                     
#                           15.2.2013                            
#                  Tested with EPrints 3.3.11                   
#
#  
#  This script is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#  
#  The script is distributed in the hope that it will be useful, but
#  WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#  General Public License for more details.
#
#######################################################################

use FindBin;
use lib "$FindBin::Bin/../perl_lib";
use open ':utf8';

use EPrints;
use strict;

# Example:
# /opt/eprints3/bin/eprints2redif.pl mpra RePEc:pra:mprapa
# mpra = repository_id 
# RePEc:pra:mprapa = RePEc handle for the MPRA Archive

my $repoid = shift @ARGV;
my $handle = shift @ARGV;
my $eprints = EPrints->new;
my $session = $eprints->repository( $repoid );
if( !defined $session )
{
	print STDERR "Failed to load repository: $repoid\n";
	exit 1;
}

my $repec_path = $handle;
$repec_path =~ s/^(\w+):(\w+):(\w+)$/$1\/$2\/$3/;
my $static_path = $session->get_conf( 'config_path' ) . '/static/' . $repec_path;
my $rdf_file = $handle;
$rdf_file =~ s/^(\w+):(\w+):(\w+)$/$3\.rdf/;
my $rdf_file_path = $static_path . "/$rdf_file";


open (FILE, ">$rdf_file_path") || die "Could not open ReDIF file $rdf_file_path";

my $dataset = $session->get_dataset( 'archive' );
my $results = $dataset->search( filters => [ { meta_fields => [qw( type )], value => 'paper' , match => 'EX' }]);
$results->map (sub
{
	my( $session, $dataset, $eprint ) = @_;

	my $succeeds = $session->get_archive()->get_dataset( "archive" )->get_field( "succeeds" );
	my $flag = { has_multiple_versions => $eprint->in_thread( $succeeds) };

	my $eprintid = $eprint->get_value( "eprintid" );
	my $first  = $eprint->first_in_thread( $succeeds );
	my $first_eprintid  = $first->get_value( "eprintid" );
		
	my $list = $eprint->later_in_thread( $succeeds );
	my @data = ();
	
	if ( $flag->{ has_multiple_versions } != 1 )
	{
		push @data, "Template-type: ReDIF-Paper 1.0\n";
		push @data, &metadata;
		push @data, "File-URL: ".$eprint->get_url."\n";
		push @data, "File-Format: application/pdf\n";
		push @data, "File-Function: original version\n";
	}
	if ( $flag->{ has_multiple_versions } == 1)
	{
		no warnings;
		next if $first_eprintid != $eprintid;
		push @data, "Template-type: ReDIF-Paper 1.0\n";
		push @data, &metadata;
		push @data, $eprint->render_repec_versions( $succeeds );
		use warnings;
	}
	push @data, "Handle:".$handle.":".$first_eprintid."\n\n\n";
	print FILE @data;
});

$session->terminate();
close FILE;

sub EPrints::DataObj::EPrint::render_repec_versions
{
	my( $self, $field ) = @_;

	my $pub = "thread_".$field->get_name;
	my @data = ();
	
	$self->map_thread( $field, sub {
		my( $session, undef, $item, $level ) = @_;

		my $succeeds = $session->get_archive()->get_dataset( "archive" )->get_field( "succeeds" );
		my $first = $item->first_in_thread( $succeeds );
		my $first_eprintid  = $first->get_value( "eprintid" );
		my $eprintid = $item->get_value( "eprintid" );
		
		push @data, "File-URL: ".$item->get_url( $pub )."\n";
		push @data, "File-Format: application/pdf\n";
		if ( $first_eprintid == $eprintid )
		{
			push @data, "File-Function: original version\n";
		}
		else {
			push @data, "File-Function: revised version\n";
		}
	});
	return @data;
}


sub metadata {
	my( $session, $eprint, $latest ) = @_;
	my @data = ();
	# Authors
	if( $latest->exists_and_set( "creators_name" ) )
	{
		my $creators = $latest->get_value( "creators_name" );
		if( defined $creators )
		{
			foreach my $creator ( @{$creators} )
			{	
				next if !defined $creator;
				$creator = EPrints::Utils::make_name_string( $creator );
				push @data, "Author-Name: ".$creator."\n";
			}
		}
	}
	
	# Title
	if( $latest->exists_and_set( "title" ) )
	{
		my $original_title = $latest->get_value( "title" );
		if( defined $original_title )
		{
			push @data, "Title: ".$original_title."\n"
		}
	}
	
	# Keywords
	if( $latest->exists_and_set( "keywords" ) )
	{
		my $keywords = $latest->get_value( "keywords" );
		if( defined $keywords )
		{
			push @data, "Keywords: ".$keywords."\n"

		}
	}
	
	# Abstract
	if( $latest->exists_and_set( "abstract" ) )
	{
		my $abstract = $latest->get_value( "abstract" );
		if( defined $abstract )
		{
			push @data, "Abstract: ".$abstract."\n"
		}
	}
	
	# Subjects; in case of MPRA, the subjects are based on JEL classification
	if( $latest->exists_and_set( "subjects" ) )
	{
		push @data, "Classification-JEL: ";
		foreach my $subjectid ( @{$latest->get_value( "subjects" )} )
		{
			push @data, $subjectid."; ";
		}
		push @data, "\n";
	}
	
	# Creation date
	if( $latest->exists_and_set( "date" ) )
	{
		my $date = $latest->get_value( "date" );
		if( defined $date )
		{
			push @data, "Creation-Date: ".$date."\n"
		}
	}
	
	# Revision date
	if( $latest->exists_and_set( "date_revision" ) )
	{
		my $date = $latest->get_value( "date_revision" );
		if( defined $date )
		{
			push @data, "Revision-Date: ".$date."\n"
		}
	}
	
	# Publication status
	my $journal = $latest->get_value( "journal" );
	my $issue = $latest->get_value( "issue" );
	my $volume = $latest->get_value( "volume" );
	my $pagerange = $latest->get_value( "pagerange" );
	my $ispublished = $latest->get_value( "ispublished" );
	my $date_pub = $latest->get_value( "date_pub" );
	my $date_pub_year;
	if (defined $date_pub )
	{
		my @date_pub_all = split('-', $date_pub);
		$date_pub_year = $date_pub_all[0];
	}
	if ( defined $ispublished && $journal && $issue && $volume && $date_pub_year && $pagerange )
	{
		if ( $ispublished eq "pub" )
		{
			push @data, "Publication-Status: Published in "
			.$journal." ".$issue.".".$volume."(".$date_pub_year."): pp. ".$pagerange."\n";
		}
		if ( $ispublished eq "inpress" )
		{
			push @data, "Publication-Status: Forthcoming in "
			.$journal." ".$issue.".".$volume."(".$date_pub_year."): pp. ".$pagerange."\n";
		}
	}
	return @data;
}
exit;
