#!/usr/bin/env ruby
#
# PRIME: PRedictive Input Method Editor
# $Id: prime.src,v 1.7 2005/03/07 07:51:34 komatsu Exp $
#
# Copyright (C) 2001 Satoru Takabayashi <satoru@namazu.org>
# Copyright (C) 2002, 2003 Hiroyuki Komatsu <komatsu@taiyaki.org>
#     All rights reserved.
#     This is free software with ABSOLUTELY NO WARRANTY.
#
# You can redistribute it and/or modify it under the terms of 
# the GNU General Public License version 2.
#

PRIME_BINDIR = '/usr/bin'
PRIME_LIBDIR = '/usr/lib/site_ruby/1.8'
$LOAD_PATH.unshift(PRIME_LIBDIR) unless $LOAD_PATH.member?(PRIME_LIBDIR)

require 'getoptlong'
require 'prime/prime'
require 'prime/protocol'
require 'prime/server'
require "jcode"

PRIME_VERSION = '1.0.0.1'

class PrimeCommand
  def initialize ()
    @options = parse_options()

    if PRIME_ENV['typing_method'] then
      PrimeTypeConv::destroy_cache()
    end

    @prime = Prime.new()

    if PRIME_ENV['typing_method'] then
      PrimeTypeConv::destroy_cache()
    end
  end

  def show_usage
    puts "\
Usage: #{command_name} <options>
  -u, --unix-socket=PATH      run as Unix socket server with socket PATH
  -s, --tcp-server=PORT       run as TCP server with port PORT
  -v, --version               show the version and exit
  -h, --help                  show this help and exit
      --no-save               do not save learning records
      --typing-method=METHOD  run with the specified typing method.
  -d, --debug                 run under debug mode

      --skk                   run as SKK Server
      --pobox                 run as POBox Server

HomePage: http://taiyaki.org/prime/ (in Japanese)
"
  end

  def command_name
    $0.split('/').last
  end

  def parse_options
    options = Hash.new

    parser = GetoptLong.new
    parser.set_options(['--help', '-h',         GetoptLong::NO_ARGUMENT],
                       ['--version','-v',	GetoptLong::NO_ARGUMENT],
                       ['--unix-socket', '-u',	GetoptLong::REQUIRED_ARGUMENT],
                       ['--tcp-server',	'-s',	GetoptLong::OPTIONAL_ARGUMENT],
                       ['--typing-method',      GetoptLong::REQUIRED_ARGUMENT],
                       ['--char-encoding',      GetoptLong::REQUIRED_ARGUMENT],
                       ['--no-save',            GetoptLong::NO_ARGUMENT],
                       ['--debug', '-d',	GetoptLong::NO_ARGUMENT],
                       ['--skk',	        GetoptLong::OPTIONAL_ARGUMENT],
                       ['--pobox',	        GetoptLong::OPTIONAL_ARGUMENT],
                       ['--network-dict',       GetoptLong::REQUIRED_ARGUMENT])

    parser.each_option {|option, arg|
      options[option.sub(/^--/, '')] = arg
    }

    if options['version'] then
      puts "#{command_name} #{PRIME_VERSION}"
      exit 1
    end

    if options['no-save'] then
      $PRIME_NO_SAVE = true
    else
      $PRIME_NO_SAVE = false
    end

    if options['help'] then
      show_usage()
      exit 1
    end

    if options['debug'] or ENV['PRIME_DEBUG'] then
      PRIME_ENV['debug'] = true
    else
      PRIME_ENV['debug'] = false
    end
    
    typing_method = (options['typing-method']   || \
                     ENV['PRIME_TYPING_METHOD'] || \
                     PRIME_ENV['typing_method'] )
    PRIME_ENV['typing_method'] = typing_method

    char_encoding = (options['char-encoding']   || \
                     ENV['PRIME_CHAR_ENCODING'] || \
                     PRIME_ENV['char_encoding'] )
    PRIME_ENV['char_encoding'] = char_encoding

    ## Configurating a network-dict (Experimental)
    network_dict = options['network-dict']
    if network_dict then
      unless PRIME_ENV['engines'].member?(:PrimeEngineNetwork) then
        PRIME_ENV['engines'].push(:PrimeEngineNetwork)
      end
      unless PRIME_ENV['engine_network_servers'].member?(network_dict) then
        PRIME_ENV['engine_network_servers'].push(network_dict)
      end
    end

    return options
  end

  def main ()
    @prime.update()

    if @options['skk'] then
      tcp_port = @options['skk'].empty?() ? "1178" : @options['skk']
      @options['tcp-server'] = tcp_port
      protocol = PrimeProtocolSKK.new(@prime, PRIME_VERSION)
    elsif @options['pobox'] then
      tcp_port = @options['pobox'].empty?() ? "1179" : @options['pobox']
      @options['tcp-server'] = tcp_port
      protocol = PrimeProtocolPOBox.new(@prime, PRIME_VERSION)
    else
#      protocol = ProtocolPrime.new(@prime, PRIME_VERSION)
      protocol = PrimeProtocolPrime2.new(@prime, PRIME_VERSION)
    end

    if @options['unix-socket'] then
      socket_path = @options['unix-socket']
      server = UnixSocketServer.new(protocol, socket_path)
    elsif @options['tcp-server'] then
      tcp_port = (@options['tcp-server'].empty?() ?
		  "1180" : @options['tcp-server'])
      server = TaiyakiTCPServer.new(protocol, tcp_port)
    else
      server = StdioServer.new(protocol)
    end

    if PRIME_ENV['debug'] then
      server.set_debug()
    end
    if PRIME_ENV['char_encoding'] then
      server.set_encoding(PRIME_ENV['char_encoding'])
    end

    server.start()

    @prime.close()
  end

  def refresh ()
    @prime.refresh()
  end
end

trap ("INT") {
  $stderr.puts "Interrupted."
  exit()
}
prime = PrimeCommand.new()

trap ("HUP") {
  prime.refresh()
}

prime.main()
