///|
fn main {
  let tokenizers = @lib.TokenizerManager::with_defaults()
  let schema_builder = @lib.SchemaBuilder::new()
  let title = schema_builder.add_text_field(
    "title",
    @lib.TextOptions::new(true, true).with_tokenizer("en_stem"),
  )
  let body = schema_builder.add_text_field(
    "body",
    @lib.TextOptions::new(true, true).with_tokenizer("en_stem"),
  )
  let schema = schema_builder.build()
  let first_segment_writer = @lib.SegmentWriter::with_schema_and_tokenizers(
    schema, tokenizers,
  ) catch {
    error => abort(error.to_string())
  }
  let doc0 = @lib.Document::new()
  doc0.add_text(title, "MoonSearch")
  doc0.add_text(body, "moonbit search engine")
  let doc1 = @lib.Document::new()
  doc1.add_text(title, "MoonBit guide")
  doc1.add_text(body, "language documentation")
  ignore(first_segment_writer.add_document(doc0))
  ignore(first_segment_writer.add_document(doc1))
  let directory = @lib.MemoryDirectory::new()
  let index_writer = @lib.IndexWriter::new(directory)
  index_writer.commit(first_segment_writer.finish()) catch {
    error => abort(error.to_string())
  }
  let old_reader = @lib.IndexReader::open(directory) catch {
    error => abort(error.to_string())
  }
  let second_segment_writer = @lib.SegmentWriter::with_schema_and_tokenizers(
    schema, tokenizers,
  ) catch {
    error => abort(error.to_string())
  }
  let doc2 = @lib.Document::new()
  doc2.add_text(title, "Search notes")
  doc2.add_text(body, "moonbit full text search")
  ignore(second_segment_writer.add_document(doc2))
  index_writer.commit(second_segment_writer.finish()) catch {
    error => abort(error.to_string())
  }
  let before_delete_reader = @lib.IndexReader::open(directory) catch {
    error => abort(error.to_string())
  }
  index_writer.delete_term(@lib.Term::new(title, "moonbit")) catch {
    error => abort(error.to_string())
  }
  index_writer.commit_deletes() catch {
    error => abort(error.to_string())
  }
  let after_delete_reader = @lib.IndexReader::open(directory) catch {
    error => abort(error.to_string())
  }
  index_writer.merge() catch {
    error => abort(error.to_string())
  }
  index_writer.close()
  let merged_reader = @lib.IndexReader::open(directory) catch {
    error => abort(error.to_string())
  }
  let searcher = merged_reader.searcher() catch {
    error => abort(error.to_string())
  }
  let parser = @lib.QueryParser::new(schema, tokenizers)
  let title_query = parser.parse_query(title, "SEARCHES") catch {
    error => abort(error.to_string())
  }
  let body_query = parser.parse_query(body, "MOONBIT") catch {
    error => abort(error.to_string())
  }
  let boosted_title = @lib.BoostQuery::new(title_query, 3.0)
  let boosted_body = @lib.BoostQuery::new(body_query, 1.0)
  let query = @lib.BooleanQuery::new([
    @lib.BooleanClause::new(@lib.Occur::Should, boosted_title),
    @lib.BooleanClause::new(@lib.Occur::Should, boosted_body),
  ])
  let hits = searcher.search(query, @lib.TopKCollector::new(10))
  let old_count = old_reader.segment_count() catch {
    error => abort(error.to_string())
  }
  let before_delete_count = before_delete_reader.segment_count() catch {
    error => abort(error.to_string())
  }
  let after_delete_count = after_delete_reader.segment_count() catch {
    error => abort(error.to_string())
  }
  let merged_count = merged_reader.segment_count() catch {
    error => abort(error.to_string())
  }
  println(
    "MoonSearch M5b-2 English analysis: old=\{old_count} before_delete=\{before_delete_count} after_delete=\{after_delete_count} merged=\{merged_count}",
  )
  for hit in hits {
    let doc_id = hit.address.doc_id
    let segment_ord = hit.address.segment_ord
    match searcher.doc(hit.address) {
      Some(document) => {
        let titles = document.texts_for(title)
        println(
          "  segment\{segment_ord}/doc\{doc_id.value} score=\{hit.score} title=\"\{titles[0]}\"",
        )
      }
      None =>
        println("  segment\{segment_ord}/doc\{doc_id.value} score=\{hit.score}")
    }
  }
  old_reader.close()
  before_delete_reader.close()
  after_delete_reader.close()
  merged_reader.close()
}