use KinoSearch::Index::Indexer;
use KinoSearch::Plan::Schema;
use KinoSearch::Analysis::PolyAnalyzer;
use KinoSearch::Plan::FullTextType;

# Create a Schema which defines index fields.
my $schema = KinoSearch::Plan::Schema->new;
my $polyanalyzer = KinoSearch::Analysis::PolyAnalyzer->new( 
	language => 'en',
);
my $type = KinoSearch::Plan::FullTextType->new(
	analyzer => $polyanalyzer,
);
my $blob_type = KinoSearch::Plan::BlobType->new( stored => 1 );
my $string_type = KinoSearch::Plan::StringType->new;
$schema->spec_field( name => '_id',   type => $string_type );
$schema->spec_field( name => '_rev', type => $string_type );
$schema->spec_field( name => 'doc', type => $blob_type );

# Create the index and add documents.
our $indexer;


sub _indexer {
	$indexer ||= KinoSearch::Index::Indexer->new(
		schema => $schema,   
		index  => '/tmp/index',
		create => 1,
	);
};

sub flatten {
	my ($flat,$data,$prefix) = @_;
	if ( ref $data eq '' ) {
		$$flat->{$prefix} = $data;
	} elsif ( ref $data eq 'HASH' ) {
		foreach my $key ( keys %$data ) {
			my $full_prefix = $prefix ? $prefix . '.' : '';
			$full_prefix .= $key;
			flatten( $flat, $data->{$key}, $full_prefix );
		}
	} elsif ( ref $data eq 'ARRAY' ) {
		$$flat->{$prefix} = join("\n", map { ref $_ ? dump($_) : $_ } @$data);
		# FIXME arrays with non-scalar references aren't really indexed well
	}
}

sub filter {
	my $change = shift;
	my $doc = $change->{doc} || next;
	my $flat;
	flatten( \$flat, $doc, '' );
	foreach my $field ( keys %$flat ) {
		next if $schema->fetch_type($field);
		$schema->spec_field( name => $field, type => $type );
		warn "# +++ $field\n";
	}
	$flat->{doc} = $json->encode($doc);
	warn "# add_doc ",dump($flat);
	_indexer->add_doc($flat);
	return 0;
}

sub commit {
	return unless $indexer;
	$indexer->commit;
	undef $indexer;
	warn "# commit index done\n";
}

1;
