###############################################################################
#
# STDOUTXML.pm -- A dbutil implementation that, hopefully unsurprisingly,
# writes infodb stuff as XML to STDOUT. This will be used as part of the Hadoop
# process - where this output will be passed through to the reduce phase to be
# merged with other documents.
#
# A component of the Greenstone digital library software from the New Zealand
# Digital Library Project at the University of Waikato, New Zealand.
#
# Copyright (c) 2015 New Zealand Digital Library Project
#
# This program 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.
#
# This program 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.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 675 Mass
# Ave, Cambridge, MA 02139, USA.
#
###############################################################################

package DBDrivers::STDOUTXML;

# Pragma
use strict;

# Libraries
# - Perl built-in modules
use Time::HiRes qw( gettimeofday );
# - Greenstone modules
use FileUtils;
use parent 'DBDrivers::BaseDBDriver';

## @function
sub new
{
    my $class = shift(@_);
    my $self = DBDrivers::BaseDBDriver->new(@_);
    $self->{'default_file_extension'} = 'gdb';
    $self->{'type'} = 'doc';
    # Optional Support
    $self->{'supports_datestamp'} = 1;
    $self->{'supports_rss'} = 1;
    $self->{'supports_set'} = 1;
    $self->{'write_only'} = 1;
    bless($self, $class);
    return $self;
}
## new(integer) => STDOUTXML ##

# -----------------------------------------------------------------------------
#   STDOUT XML IMPLEMENTATION
# -----------------------------------------------------------------------------


## @function open_infodb_write_handle()
#
# Since we are writing to STDOUT we don't have to open a handle
#
sub open_infodb_write_handle
{
    my $self = shift(@_);
    $self->debugPrintFunctionHeader(@_);
    my $infodb_file_path = shift(@_);
    my $opt_append = shift(@_);
    # Store this for later
    $self->{'type'} = $infodb_file_path;
    return 1;
}
## open_infodb_write_handle() ##


## @function
#
# In this function we not close the handle we didn't open :P
#
sub close_infodb_write_handle
{
    my $self = shift(@_);
    $self->debugPrintFunctionHeader(@_);
    my $infodb_handle = shift(@_);
}
## close_infodb_write_handle() ##


## @function delete_infodb_entry()
#
sub delete_infodb_entry
{
    my $self = shift(@_);
    $self->debugPrintFunctionHeader(@_);
    my $infodb_handle = shift(@_);
    my $infodb_key = shift(@_);
    print STDERR "\@TODO: implement delete_infodb_entry()\n";
}
## delete_infodb_entry() ##


## @function get_infodb_file_path()
#
sub get_infodb_file_path
{
    my $self = shift(@_);
    $self->debugPrintFunctionHeader(@_);
    my $collection_name = shift(@_);
    my $infodb_directory_path = shift(@_);
    my $infodb_type = 'error';
    if ($collection_name =~ /(datestamp|doc|src|rss)/)
    {
	$infodb_type = $1;
    }
    return $infodb_type;
}
## get_infodb_file_path(string, string) => string ##


## @function read_infodb_entry()
#
sub read_infodb_entry
{
    my $self = shift(@_);
    $self->debugPrintFunctionHeader(@_);
    my $infodb_file_path = shift(@_);
    my $infodb_key = shift(@_);
    print STDERR "\@TODO: implement read_infodb_entry()\n";
}
## read_infodb_file() ##


## @function read_infodb_file()
#
sub read_infodb_file
{
    my $self = shift(@_);
    $self->debugPrintFunctionHeader(@_);
    my $infodb_file_path = shift(@_);
    my $infodb_map = shift(@_);
    print STDERR "\@TODO: implement read_infodb_file()\n";
}
## read_infodb_file() ##


## @function read_infodb_keys()
#
sub read_infodb_keys
{
    my $self = shift(@_);
    $self->debugPrintFunctionHeader(@_);
    my $infodb_file_path = shift(@_);
    my $infodb_map = shift(@_);
    print "!implement read_infodb_keys()\n";
}
## read_infodb_keys() ##


sub set_infodb_entry
{
    my $self = shift(@_);
    $self->debugPrintFunctionHeader(@_);
    my $infodb_file_path = shift(@_);
    my $infodb_key = shift(@_);
    my $infodb_map = shift(@_);
    my $status = undef;
    print STDERR "\@TODO: implement set_infodb_entry()\n";
    return $status;
}
## set_infodb_entry() ##


## @function write_infodb_entry()
#
sub write_infodb_entry
{
    my $self = shift(@_);
    $self->debugPrintFunctionHeader(@_);
    my $infodb_handle = shift(@_);
    my $infodb_key = shift(@_);
    my $infodb_map = shift(@_);
    my @values;
    foreach my $infodb_value_key (sort keys(%$infodb_map))
    {
	foreach my $infodb_value (@{$infodb_map->{$infodb_value_key}})
	{
	    if ($infodb_value =~ /-{70,}/)
	    {
		# if value contains 70 or more hyphens in a row we need to escape them
		# to prevent txt2db from treating them as a separator
		$infodb_value =~ s/-/&\#045;/gi;
	    }
	    push(@values, '<' . $infodb_value_key . '>' . $infodb_value);
	}
    }
    my $values_str = join("\n", @values);
    $values_str =~ s/&/&amp;/g;
    $values_str =~ s/</&lt;/g;
    $values_str =~ s/>/&gt;/g;
    $values_str =~ s/"/&quot;/g;
    $values_str =~ s/'/&apos;/g;
    my ($seconds, $microseconds) = gettimeofday();
    print '<InfoDBEntry type="' . $self->{'type'} . '" key="' . $infodb_key . '" mode="set" timestamp="' . $seconds . '.' . $microseconds . '">' . $values_str . '</InfoDBEntry>' . "\n";
}
## write_infodb_entry() ##


## @function write_infodb_rawentry()
#
sub write_infodb_rawentry
{
    my $self = shift(@_);
    $self->debugPrintFunctionHeader(@_);
    my $infodb_handle = shift(@_);
    my $infodb_key = shift(@_);
    my $infodb_val = shift(@_);
    $infodb_val =~ s/&/&amp;/g;
    $infodb_val =~ s/</&lt;/g;
    $infodb_val =~ s/>/&gt;/g;
    $infodb_val =~ s/"/&quot;/g;
    $infodb_val =~ s/'/&apos;/g;
    my ($seconds, $microseconds) = gettimeofday();
    print '<InfoDBEntry type="' . $self->{'type'} . '" key="' . $infodb_key . '" mode="set" timestamp="' . $seconds . '.' . $microseconds . '">' . $infodb_val . '</InfoDBEntry>' . "\n";
}
## write_infodb_rawentry(filehandle, string, string) => void ##


1;
