package BackupPC::Search::Estraier;
use warnings;
use strict;

use Search::Estraier 0.04;

my $debug = $ENV{DEBUG} || 0;

sub new {
	my ( $class, $index_node_url ) = @_;

	warn "# using $index_node_url";

	my $self = bless {
		node => Search::Estraier::Node->new(
			url => $index_node_url,
			user => 'admin',
			passwd => 'admin',
			croak_on_error => 1,
		),
	}, $class;
	return $self;
}

sub node { $_[0]->{node} };

sub exists {
	my ( $self, $row ) = @_;

	my $uri = $row->{hname} . ':' . $row->{sname} . '#' . $row->{backupnum} . ' ' . $row->{filepath};
	my $id = $self->node->uri_to_id($uri);
	return $id && $id != -1;
}

sub add_doc {
	my ( $self, $row ) = @_;

	# create a document object 
	my $doc = Search::Estraier::Document->new;

	my $uri = $row->{hname} . ':' . $row->{sname} . '#' . $row->{backupnum} . ' ' . $row->{filepath};
	# add attributes to the document object 
	$doc->add_attr('@uri', $uri);

	foreach my $c (keys %$row) {
		print STDERR "attr $c = $row->{$c}\n" if ($debug > 2);
		$doc->add_attr($c, $row->{$c}) if defined($row->{$c});
	}

	#$doc->add_attr('@cdate', fmt_date($row->{'date'}));

	# add the body text to the document object 
	my $path = $row->{'filepath'};
	$doc->add_text($path);
	$path =~ s/(.)/$1 /g;
	$doc->add_hidden_text($path);

	print STDERR $doc->dump_draft,"\n" if ($debug > 1);

	# register the document object to the database
	$self->node->put_doc($doc);

}

sub commit {
	my $self = shift;
	warn "# commit not needed";
}

my $sort_mapping = {
	share_d => 'sname STRD',
	share_a => 'sname STRA',
	path_d => 'filepath STRD',
	path_a => 'filepath STRA',
	num_d => 'backupnum NUMD',
	num_a => 'backupnum NUMA',
	size_d => 'size NUMD',
	size_a => 'size NUMA',
	date_d => 'date NUMD',
	date_a => 'date NUMA',
};

sub search {
	my ( $self, $offset, $on_page, $sort, $q, $shareid, $backup_from, $backup_to, $files_from, $files_to ) = @_;

	warn "# search $offset/$on_page [$q] shareid: $shareid backup: $backup_from - $backup_to files: $files_from - $files_to";

	# create a search condition object
	my $cond = Search::Estraier::Condition->new();

	if (length($q) > 0) {
		# exact match
		$cond->add_attr("filepath ISTRINC $q");

		$q =~ s/(.)/$1 /g;
		# set the search phrase to the search condition object
		$cond->set_phrase($q);
	}

	$cond->add_attr("backup_date NUMGE $backup_from") if ($backup_from);
	$cond->add_attr("backup_date NUMLE $backup_to") if ($backup_to);

	$cond->add_attr("date NUMGE $files_from") if ($files_from);
	$cond->add_attr("date NUMLE $files_to") if ($files_to);

	$cond->add_attr("shareid NUMEQ $shareid") if ($shareid);

	$cond->set_max( $offset + $on_page );
	$cond->set_options( 'SURE' );
	$cond->set_order( $sort_mapping->{$sort} );

	# get the result of search
	my @res;
	my ($result, $hits);

	$result = $self->node->search($cond, 0);
	if ($result) {
		$hits = $result->hits;
	} else {
		return (0,[]);
	}

	# for each document in result
	for my $i ($offset .. ($offset + $on_page - 1)) {
		last if ($i >= $result->doc_num);

		my $doc = $result->get_doc($i);

		my $row;
		foreach my $c (qw/fid hname sname backupnum filepath date type size/) {
			$row->{$c} = $doc->attr($c);
		}
		push @res, $row;
	}

	warn "# $hits hits";

	return ($hits, \@res);

}

1;
