######################################################################
#
#  EPrints Repository Info Exporter
#
######################################################################
#
#  __COPYRIGHT__
#
# Copyright 2000-2010 University of Southampton. All Rights Reserved.
# 
#  __LICENSE__
#
######################################################################

use EPrints;
use EPrints::Const qw( :http );

use Digest::MD5;
use EPrints::Sword::Utils;
 
use Apache2::RequestRec ();
use Apache2::RequestIO ();

use strict;
my $repository = EPrints->new->current_repository;
exit( 0 ) unless( defined $repository );
# $repository->get_database->set_debug( 1 );

my $path_info = $repository->get_request->path_info;

# path is one of:
# /$id/ (eprints list of formats)
# /$id/$format/$prettyname (eprints)
# /repository/$format/$prettyname
# /dump/$format/$prettyname
# /subject/$id/$format/$prettyname
# /x-foo/$id/$format/$prettyname

my @path = split( '/', $path_info );
shift @path; # lose leading /

if( $path[0] =~ m/^\d+$/ && scalar @path == 1 )
{
	show_eprint_export_options( $repository, $path[0] );
	exit;
}

my $prettyname = pop @path;
my $format = pop @path;

unless( defined $format )
{
	$repository->not_found;
	exit;
}

my $plugin = $repository->plugin( "Export::$format" );
if( !$plugin )
{
	$repository->not_found;
	exit;
}

if( $plugin->param( "visible" ) eq "staff" )
{
	my $user = $repository->current_user;
	if( !defined $user )
	{
		my $rc = EPrints::Apache::Auth::authen( $repository->get_request );
		if( $rc != OK )
		{
			$repository->get_request->status( $rc );
			exit;
		}
		$user = $repository->current_user;
	}
	if( $user->get_type ne "editor" && $user->get_type ne "admin" )
	{
		$repository->get_request->status( HTTP_FORBIDDEN );
		exit;
	}
}

my %arguments = %{$plugin->param( "arguments" )};
# fetch the plugin arguments, if any
foreach my $argname (keys %arguments)
{
	if( defined $repository->param( $argname ) )
	{
		$arguments{$argname} = $repository->param( $argname );
	}
}

if( $path[0] =~ m/^\d+$/ && scalar @path == 1 )
{
	export_dataobj( $repository, $plugin, \%arguments, "eprint", $path[0] );
}
elsif( $path[0] eq "repository" && scalar @path == 1 )
{
	export_rdf_repository( $repository, $plugin, \%arguments );
}
elsif( $path[0] eq "dump" && scalar @path == 1 )
{
	export_rdf_dump( $repository, $plugin, \%arguments );
}
elsif( $path[0] eq "subject" && scalar @path == 2 )
{
	export_subject( $repository, $plugin, \%arguments, $path[1] );
}
elsif( $path[0] eq "records" && scalar @path == 1) 
{
	export_eprints( $repository, $plugin, \%arguments );
}
elsif( $path[1] =~ m/^ext-/ && scalar @path == 2 )
{
	export_rdf_resource( $repository, $plugin, \%arguments, $path[0], $path[1] );
}
elsif( scalar @path == 2 )
{
	export_dataobj( $repository, $plugin, \%arguments, @path[0,1] );
}
else
{
	$repository->not_found;
}
	
exit;

# Export all eprints owned by logged in user
sub export_eprints 
{	
	my( $repository, $plugin, $args ) = @_;

	my $user = $repository->current_user;
	if( !defined $user )
	{
		my $rc = EPrints::Apache::Auth::authen( $repository->get_request );
		if( $rc != OK )
		{
			$repository->get_request->status( $rc );
			exit;
		} 
		$user = $repository->current_user;
	}

	my $list = $user->owned_eprints_list(order=>"datestamp");
	
	$plugin->initialise_fh( \*STDOUT );
	
	$repository->send_http_header( "content_type"=>$plugin->param("mimetype") );
	
	$plugin->output_list( fh=>\*STDOUT, list=>$list );
}


# Dump ALL eprint triples. Not Subject or repository ones, though.
sub export_rdf_dump
{
	my( $repository, $plugin, $args ) = @_;

	if( !$plugin->can_accept( "list/triple" ) )
	{
		$repository->not_found;
		exit;
	}

	my $searchexp = EPrints::Search->new(
			allow_blank => 1,
			dataset => $repository->dataset( "triple" ),
			session => $repository );
	my $list = $searchexp->perform_search;
	$plugin->initialise_fh( \*STDOUT );
	$repository->send_http_header( "content_type"=>$plugin->param("mimetype") );
	$plugin->output_list( fh=>\*STDOUT, list=>$list );
}

sub export_rdf_repository
{
	my( $repository, $plugin, $args ) = @_;

	if( !$plugin->can_accept( "list/triple" ) )
	{
		$repository->not_found;
		exit;
	}

	my $repository_uri = "<".$repository->config( "base_url" )."/id/repository>";

	my $graph = EPrints::RDFGraph->new( repository=>$repository );
	$graph->add( 
		  subject => "<>",
		predicate => "foaf:primaryTopic",
		   object => $repository_uri );
	$graph->add_boilerplate_triples();	
	$graph->add_repository_triples();

	$repository->send_http_header( "content_type"=>$plugin->param("mimetype") );
	$plugin->initialise_fh( \*STDOUT );
	print $plugin->output_graph( $graph );
}

sub export_subject
{
	my( $repository, $plugin, $args, $subject_id ) = @_;

	if( !$plugin->can_accept( "list/subject" ) )
	{
		$repository->not_found;
		exit;
	}

	my $subject = $repository->dataset( "subject" )->dataobj( $subject_id );
	if( !defined $subject )
	{
		$repository->not_found;
		return;
	}

	my $list = $repository->dataset( "subject" )->search( 
		filters => [
			{
				meta_fields => [qw/ ancestors /],
				value => $subject_id,
			}
		],
	);

	$repository->send_http_header( "content_type"=>$plugin->param("mimetype") );
	$plugin->initialise_fh( \*STDOUT );

	print $list->export( $plugin->get_subtype, %{$args} );
}

sub export_rdf_resource
{
	my( $repository, $plugin, $args, $resource_type, $resource_id ) = @_;

	if( !$plugin->can_accept( "list/triple" ) )
	{
		$repository->not_found;
		exit;
	}

	my $uri = "epid:$resource_type/$resource_id";
	my $list = $repository->dataset( "triple" )->search( 
		filters => [
			{
				meta_fields => [qw/ secondary_resource /],
				value => $uri,
			}
		],
	);

	if( !$list->count )
	{
		$repository->not_found;
		exit;
	}

	my $graph = EPrints::RDFGraph->new( repository=>$repository );
	$graph->add( 
		  subject => "<>",
		predicate => "foaf:primaryTopic",
		   object => $uri );
	$graph->add_boilerplate_triples();	

	$list->map( sub{ 
		my( $session, $dataset, $dataobj ) = @_;
		$graph->add_dataobj_triples( $dataobj );
	} );

	$repository->send_http_header( "content_type"=>$plugin->param("mimetype") );
	$plugin->initialise_fh( \*STDOUT );
	
	print $plugin->output_graph( $graph, %{$args} );
}

sub export_dataobj
{
	my( $repository, $plugin, $args, $datasetid, $id ) = @_;

	my $r = $repository->get_request;

	my $dataset = $repository->dataset( $datasetid );
	$repository->not_found( "No such dataset" ), exit if !defined $dataset;

	if( !$plugin->can_accept( "dataobj/".$dataset->base_id ) )
	{
		$repository->not_found;
		exit;
	}

	my $dataobj = $dataset->dataobj( $id );
	$repository->not_found( "No such dataobj" ), exit if !defined $dataobj;

	if( $dataobj->isa( "EPrints::DataObj::EPrint" ) )
	{
		$dataset = $dataobj->get_dataset;
	}

	my $rc;

	my $crud = EPrints::Apache::CRUD->new(
			repository => $repository,
			request => $r,
			dataset => $dataset,
			dataobj => $dataobj,
			plugin => $plugin,
			scope => EPrints::Apache::CRUD::CRUD_SCOPE_DATAOBJ,
		);

	$rc = $crud->authen;
	if( $rc != OK )
	{
		$r->status( $rc );
		return;
	}

	$rc = $crud->authz;
	if( $rc != OK )
	{
		$r->status( $rc );
		return;
	}

	$rc = $crud->handler;
	if( $rc != OK )
	{
		$r->status( $rc );
		return;
	}
}

sub show_eprint_export_options
{
	my( $repository, $eprintid ) = @_;

	my $eprint = $repository->eprint( $eprintid );
	if( !defined $eprint )
	{
		$repository->not_found;
		exit;
	}

	my $title = $repository->html_phrase( "cgi/export:title",
			shortname=>$eprint->render_description );
	my $page = $repository->html_phrase( "cgi/export:page",
		citation => $eprint->render_citation_link,
		formats => $eprint->render_export_links ); 
	$repository->build_page( $title, $page, "export" );
	$repository->send_page;
}
