#! /usr/bin/ruby

# Copyright (C) 2005  Network Applied Communication Laboratory Co., Ltd.
#
# This file is part of Rast.
# See the file COPYING for redistribution information.
#

begin
  require "rast_xmlrpc_client"
rescue LoadError
  require "rast"
end
require "optparse"

def convert(in_encoding, out_encoding, str)
  if in_encoding.downcase == out_encoding.downcase
    return str
  end
  require "iconv"
  return Iconv.iconv(out_encoding, in_encoding, str).join
end

# parse options
options = {
  "need_summary" => true,
}

OptionParser.new do |opt|
  opt.banner = "Usage: #{opt.program_name} [options] <query> [index]..."
  opt.on("--sort PROPERTY", "set a sort PROPERTY (default: score)") do |v|
    if v != "score"
      options["sort_method"] = Rast::SORT_METHOD_PROPERTY
      options["sort_property"] = v
    end
  end
  opt.on("--ascending", "sort in ascending order") do
    options["sort_order"] = Rast::SORT_ORDER_ASCENDING
  end
  opt.on("--descending", "sort in descending order") do
    options["sort_order"] = Rast::SORT_ORDER_DESCENDING
  end
  opt.on("--terminal-encoding ENCODING", "set terminal encoding") do |encoding|
    options["terminal_encoding"] = encoding
  end
  opt.on("--start-no NUMBER", "set first result item (default: 0)") do |start_no|
    options["start_no"] = start_no.to_i
  end
  opt.on("--num-items NUMBER",
         "set number of result items (default: all)") do |num_items|
    options["num_items"] = num_items.to_i
  end
  opt.on("--summary-nchars NUMBER",
         "set summary length (default: 100)") do |summary_nchars|
    options["summary_nchars"] = summary_nchars.to_i
  end
  opt.on_tail("-h", "--help", "Show this message") do
    puts opt
    exit
  end
  opt.on_tail("-v", "--version", "Show version") do
    puts "rast #{Rast::VERSION}"
    exit
  end
  opt.parse!(ARGV)
end

# get query and indices
term_query = ARGV.shift
indices = ARGV.empty? ? ["."] : ARGV.dup

begin
  rastdb_list = []

  # open indices and get properties
  indices.each do |i|
    rastdb_list.push(Rast::DB.open(i, Rast::DB::RDONLY))
  end
  properties = rastdb_list.collect do |i|
    i.properties.collect do |j|
      j.name
    end
  end
  options["properties"] = properties.flatten.uniq

  # search
  Rast::Merger.open(rastdb_list) do |db|
    db_encoding = db.encoding

    terminal_encoding = options["terminal_encoding"] || db_encoding
    query = convert(terminal_encoding, db_encoding, term_query)
    result = db.search(query, options)

    puts "search result of \"#{term_query}\""
    puts "#{result.hit_count} hits"
    puts

    for item in result.items
      puts "doc_id : #{item.doc_id}"
      puts "score : #{item.score}"
      options["properties"].each_with_index do |property, i|
        value = item.properties[i]
        if value.is_a?(String)
          value = convert(db_encoding, terminal_encoding, value)
        end

        puts "#{property} : #{value}"
      end
      summary = convert(db_encoding, terminal_encoding, item.summary)
      puts "summary : #{summary}"
      puts
    end
  end
ensure
  # close indices
  rastdb_list.each do |i|
    i.close
  end
end

# local variables:   
# mode: ruby     
# end:               
