#!/usr/bin/ruby1.8 -w

=begin
    Documentation generator for dhelp

    Copyright (C) 2005-2007  Esteban Manchado Velázquez

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
=end

# Keep the (non-existent) indentation in next line (the "PREFIX" one)
PREFIX = '/usr'
DEFAULT_INDEX_ROOT = "#{PREFIX}/share/doc/HTML"

require 'dhelp'
require 'dhelp/exporter/html'
include Dhelp

require 'commandline'
require 'find'
require 'yaml'


# Configuration class
class DhelpConf
  def initialize(path)
    @conf = YAML::load_file(path)
    @conf["search_directories"] ||= DEFAULT_SEARCH_DIRS
  end

  def to_hash
    @conf
  end

  def method_missing(meth)
    @conf[meth.to_s]
  end
end


# dhelp_parse application class
class DhelpParseApp < CommandLine::Application
  DHELP_CONF_FILE    = "/etc/dhelp.conf"
  DOC_DIR                 = '/usr/share/doc'
  DOC_BASE_DHELP_DIR      = '/var/lib/doc-base/dhelp'
  DEFAULT_SEARCH_DIRS     = [DOC_DIR, DOC_BASE_DHELP_DIR]

  def initialize
    version           "0.1.0"
    author            "Esteban Manchado Velázquez"
    copyright         "Copyright (c) 2005-2007, Esteban Manchado Velázquez"
    synopsis          "[-h] -a doc-base_file1 d-b_f2 ... | -d doc-base_file1 d-b_f2 ... | -r"
    short_description "Debian online help system parser"
    long_description  "Dhelp parser to add/remove/reindex dhelp files"

    option :help
    option :names => %w(-a), :arity => [0,-1],
           :opt_found => lambda {|opt, name, value| @action = :add;
                                                    @doc_base_files = value },
           :opt_description => "add documents registered in the given doc-base file"
    option :names => %w(-d), :arity => [0,-1],
           :opt_found => lambda {|opt, name, value| @action = :delete;
                                                    @doc_base_files = value },
           :opt_description => "remove documents registered in the given doc-base file"
    option :names => %w(-r), :arity => [0,0],
           :opt_found => lambda { @action = :reindex },
           :opt_description => "ignored, for compatibility"

    expected_args [0,0]

    @action = nil
  end


  def packaged_configured?
    File.exists? '/var/lib/dhelp/configured'
  end

  def main
    begin
      if packaged_configured?
        conf = DhelpConf.new(DHELP_CONF_FILE)
      else
        $stderr.puts "Deferring until dhelp is configured"
        exit 0
      end
    rescue Errno::ENOENT
      $stderr.puts "Can't read configuration file #{DHELP_CONF_FILE}"
      exit 1
    end

    # List of directories to look for doc-base documents
    doc_base_dirs = conf.search_directories.map {|d| File.expand_path(d)}
    pool = Dhelp::DhelpDocumentPool.new(:doc_base_dir => doc_base_dirs)

    case @action
    when :add
      @doc_base_files.each do |doc_base_file|
        if File.readable? doc_base_file
          doc_base_doc = Dhelp::DocBaseDocument.new(doc_base_file)
          pool.register(doc_base_doc)
        else
          $stderr.puts "Can't read doc-base file '#{doc_base_file}'"
          return 1
        end
      end
    when :delete
      @doc_base_files.each do |doc_base_file|
        pool.deregister(doc_base_file)
      end
    when :reindex
      # Simply ignore, the documentation directory will be up-to-date anyway.
    else
      $stderr.puts usage
      return 1
    end

    # Always executed
    exporter = Dhelp::Exporter::Html.new(pool)
    exporter.export(:dir => DEFAULT_INDEX_ROOT)
  rescue => e
    puts "#{e.class}: #{e} (#{e.backtrace.join("\n")})"
  end
end
