#!/usr/bin/env ruby
#
# gonzui.cgi - a web-based search engine of gonzui, CGI version
#
# Copyright (C) 2005 Tatsuki Sugiura <sugi@nemui.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.
#

require 'webrick'
require 'webrick/cgi'
require 'gonzui'
require 'gonzui/cmdapp'
require 'gonzui/webapp'
require 'ftools'
require 'fileutils'

## Turning around gonzui original filehandler, to delegate
## normal files to apache. But, this dose not work with ScriptAlias.
#module Gonzui
#  module URIMaker
#    def make_doc_uri(path = nil)
#      assert_non_nil(@config)
#      if path
#        return URI.path_join(File.dirname(@config.base_mount_point),
#                             Gonzui::FileHandler.mount_point,
#                             HTTPUtils.escape(path))
#      else
#        return URI.path_join(File.dirname(@config.base_mount_point),
#                             Gonzui::FileHandler.mount_point)
#      end
#    end
#  end
#end

class GonzuiCGI < WEBrick::CGI
  VERSION = "0.2.0"

  class LogIO
    def sync=(flag); end

    def initialize(out=nil)
      @need_open = false
      if out.nil? || out.empty?
        @out = nil
      elsif String === out
        @out = out
        @need_open = true
      else
        @out = out || $stderr
      end
    end

    def <<(*args)
      @out or return self
      outio = @need_open ? File.open(@out, "a") : @out
      begin 
        outio << args
      ensure
        @need_open and outio.close
      end
      self
    end
  end

  def initialize(*args)
    super
    @logger.level = WEBrick::Log::DEBUG if $DEBUG
  end

  ## backport patch for WEBrick
  def [](key)
    @config[key]
  end
  attr_reader :config
  ##

  def start(env=ENV, stdin=$stdin, stdout=$stdout)
    @gonzuiapp = Gonzui::CommandLineApplication.new
    @gonzuiapp.instance_eval { 
      def self.config; @config; end
      def self.logger; @logger; end
      @config.gonzui_log_file = nil
      opt = {}
      if env["GONZUIRC"]
        opt["gonzuirc"] = env["GONZUIRC"]
      elsif File.file?(".gonzuirc")
        opt["gonzuirc"] = ".gonzuirc"
      end
      process_common_options(opt) unless opt.empty?
      @config.gonzui_log_file = LogIO.new(@config.gonzui_log_file)
      init_logger
    }
    @catalog = Gonzui::CatalogRepository.new(@gonzuiapp.config.catalog_directory)
    super
  end


  def service(req, res)
    @logger.debug "checking DB (#{@gonzuiapp.config.db_directory})"
    raise HTTPStatus::InternalServerError.new("Can't find gonzui DB") unless
      File.directory?(@gonzuiapp.config.db_directory)

    @gonzuiapp.config.base_mount_point = req.script_name + "/"
    req.path_info = "/" if req.path_info.nil? || req.path_info.empty?
    @logger.debug "do service for path_info=#{req.path_info}"
    @dbm = Gonzui::DBM.open(@gonzuiapp.config, true)
    servlet = Gonzui::GonzuiServlet.servlets.find{ |sv|
      @logger.debug "check servlet #{sv} (mount=#{sv.mount_point})"
      if sv.mount_point == req.path_info.split(%r{/+})[1].to_s
        req.path_info.sub!(%r{^/+[^/]+}, "")
        true
      end
    }

    @logger.debug "delegate service for servlet(#{servlet.inspect})"
    raise HTTPStatus::BadRequest.new("Can't find servlet") unless servlet
    servlet.get_instance(self, @gonzuiapp.config, @gonzuiapp.logger,
                         @dbm, @catalog).service(req, res)
  end
end

if __FILE__ == $0
  GonzuiCGI.new.start
end
