#!/usr/bin/perl -w

use strict;
use OpenIsis;
use Getopt::Std;
use Data::Dumper;
use XML::Simple;
use Text::Unaccent;
require Unicode::Map8;

my $config=XMLin(undef, forcearray => [ 'isis' ], forcecontent => 1);

my %opts;

getopts('d:m:q', \%opts);

my $db_dir = $opts{d} || "ps";	# FIX

#die "usage: $0 -d [database_dir] -m [database1,database2] " if (! %opts);

#print Dumper($config->{indexer});
#print "-" x 70,"\n";

# how to convert isis code page to UTF8?
my $isis_map = Unicode::Map8->new($config->{isis_codepage}) || die;

sub isis2xml {

	my $row = shift @_;

	my $xml;

	sub isis_sf {
		my $row = shift @_;
		my $isis_id = shift @_;
		my $subfield = shift @_;
		if ($row->{$isis_id}->[0]) {
			my $sf = OpenIsis::subfields($row->{$isis_id}->[0]);
			if (! defined $subfield || length($subfield) == 0) {
				# subfield list undef, empty or no defined subfields for this record
				return $row->{$isis_id}->[0];
			} elsif ($sf->{$subfield}) {
				return $sf->{$subfield};
			}
		}
	}

	foreach my $field (keys %{$config->{indexer}}) {

		my $display_data = "";
		my $index_data = "";

		foreach my $x (@{$config->{indexer}->{$field}->{isis}}) {

			my $display_tmp = "";
			my $index_tmp = "";

			my $format = $x->{content};
			my $i = 1;	# index only
			my $d = 1;	# display only
			$i = 0 if (lc($x->{type}) eq "display");
			$d = 0 if (lc($x->{type}) eq "index");
#print "## i: $i d: $d ## $format ##";	
			# parse format
			my $prefix = "";
			if ($format =~ s/^([^\d]+)//) {
				$prefix = $1;
			}
			while ($format) {
				if ($format =~ s/^(\d\d\d)(\w?)//) {
					my $isis_tmp = isis_sf($row,$1,$2);
					if ($isis_tmp) {
#						$display_tmp .= $prefix . "/$1/$2/".$isis_tmp if ($d);
						$display_tmp .= $prefix . $isis_tmp if ($d);
						$index_tmp .= $isis_tmp." " if ($i);
#print " $isis_tmp <--\n";
					}
					$prefix = "";
				} elsif ($format =~ s/^([^\d]+)//) {
					$prefix = $1;
				} else {
					print STDERR "WARNING: unparsed format '$format'\n";
					last;
				};
			}
			# add suffix
			$display_tmp .= $prefix if ($display_tmp);

#			$display_data .= $display_tmp if ($display_tmp ne "");
#			$index_data .= $index_tmp if ($index_tmp ne "");
			$display_data .= $display_tmp;
			$index_data .= $index_tmp;

		}
#print "--display:$display_data\n--index:$index_data\n";
		$xml->{$field}->{display} .= $isis_map->tou($display_data)->utf8 if ($display_data);
		$xml->{$field}->{index} .= unac_string($config->{isis_codepage},$index_data) if ($index_data);
	
	}
	if ($xml) {
		return XMLout($xml, rootname => 'xml', noattr => 1 );
	} else {
		return;
	}
}

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

my $last_tell=0;

my @isis_dirs = ( '.' );	# use dirname as database name

if ($opts{m}) {
	@isis_dirs = split(/,/,$opts{m});
}

my @isis_dbs;

foreach (@isis_dirs) {
	if (-e $config->{isis_data}."/$db_dir/$_/LIBRI") {
		push @isis_dbs,$config->{isis_data}."/$db_dir/$_/LIBRI/LIBRI";
	}
	if (-e $config->{isis_data}."/$db_dir/$_/PERI") {
		push @isis_dbs,$config->{isis_data}."/$db_dir/$_/PERI/PERI";
	}
	if (-e $config->{isis_data}."/$db_dir/$_/AMS") {
		push @isis_dbs,$config->{isis_data}."/$db_dir/$_/AMS/AMS";
	}
	if (-e $config->{isis_data}."/$db_dir/$_/ARTI") {
#		push @isis_dbs,$config->{isis_data}."/$db_dir/$_/ARTI/ARTI";
	}
}

print STDERR "FATAL: Can't find isis database.\nPerhaps isis_data (".$config->{isis_data}.") has wrong value?\n" if (! @isis_dbs);

my $db;

foreach my $isis_db (@isis_dbs) {


	my $db = OpenIsis::open( $isis_db );
	if (0) {
#	# FIX
#	if (! $db ) {
		print STDERR "WARNING: can't open '$isis_db'\n";
		next ;
	}

	my $max_rowid = OpenIsis::maxRowid( $db );

	print STDERR "Reading database: $isis_db [$max_rowid rows]\n";

	my $last_p = 0;

#	{ my $row_id = 1;
# FIX
	for (my $row_id = 1; $row_id <= $max_rowid; $row_id++ ) {
		my $row = OpenIsis::read( $db, $row_id );
		if ($row && $row->{mfn}) {

			# output current process indicator
			my $p = int($row->{mfn} * 100 / $max_rowid);
			if ($p != $last_p) {
				printf STDERR ("%5d / %5d [%-51s] %-2d %% \r",$row->{mfn},$max_rowid,"=" x ($p/2).">", $p ) if (! $opts{q});
				$last_p = $p;
			}

			if (my $xml = isis2xml($row)) {
				print "Path-Name: $isis_db#".$row->{mfn}."\n";
				print "Content-Length: ".(length($xml)+1)."\n";
				print "Document-Type: XML\n\n$xml\n";
			}
		}
	}
	print STDERR "\n";
}


1;
__END__
##########################################################################

=head1 NAME

isis2xml.pl - read isis file and dump XML

=head1 DESCRIPTION

This command will read ISIS data file using OpenIsis perl module and
create XML file for usage with I<SWISH-E>
indexer. Dispite it's name, this script B<isn't general xml generator>
from isis files (isis allready has something like that). Output of this
script is tailor-made for SWISH-E.

=head1 AUTHOR

Dobrica Pavlinusic <dpavlin@rot13.org>

=head1 COPYRIGHT

GNU Public License (GPL) v2 or later

=head1 SEE ALSO

SWISH-E web site at http://www.swish-e.org

=cut
