#!/usr/bin/ruby
#
#
# Copyright (c) 1999-2007 Minero Aoki
#               2008-2014 Minero Aoki, Kenshi Muto
#
# This program is free software.
# You can distribute or modify this program under the terms of
# the GNU LGPL, Lesser General Public License version 2.1.
# For details of the GNU LGPL, see the file "COPYING".
#

require 'pathname'

bindir = Pathname.new(__FILE__).realpath.dirname
$LOAD_PATH.unshift((bindir + '../lib').realpath)

require 'review/book'
require 'review/tocparser'
require 'review/tocprinter'
require 'review/version'
require 'optparse'

def main
  Signal.trap(:INT) { exit 1 }
  if RUBY_PLATFORM !~ /mswin(?!ce)|mingw|cygwin|bccwin/
    Signal.trap(:PIPE, 'IGNORE')
  end
  _main
rescue Errno::EPIPE
  exit 0
end

def _main
  printer_class = ReVIEW::TextTOCPrinter
  source = nil
  upper = ReVIEW::TOCPrinter.default_upper_level
  param = {}
  book = ReVIEW::Book::Base.load

  opts = OptionParser.new
  opts.version = ReVIEW::VERSION
  opts.on('-a', '--all', 'print all chapters.') {
    source = book
  }
  opts.on('-p', '--part N', 'list only part N.') {|n|
    source = book.part(Integer(n)) or
        error_exit "part #{n} does not exist in this book"
  }
  opts.on('-c', '--chapter C', 'list only chapter C.') {|c|
    begin
      source = ReVIEW::Book::Part.new(nil, 1, [book.chapter(c)])
    rescue
      error_exit "chapter #{c} does not exist in this book"
    end
  }
  opts.on('-l', '--level N', 'list upto N level (1..4, default=4)') {|n|
    upper = Integer(n)
    unless (0..4).include?(upper) # 0 is hidden option
      $stderr.puts "-l/--level option accepts only 1..4"
      exit 1
    end
  }
  opts.on('--text', 'output in plain text (default)') {
    printer_class = ReVIEW::TextTOCPrinter
  }
  opts.on('--html', 'output in HTML (deprecated)') {
    printer_class = ReVIEW::HTMLTOCPrinter
  }
  opts.on('--help', 'print this message and quit.') {
    puts opts.help
    exit 0
  }
  begin
    opts.parse!
  rescue OptionParser::ParseError => err
    $stderr.puts err.message
    $stderr.puts opts.help
    exit 1
  end
  if source
    unless ARGV.empty?
      error_exit '-a/-s option and file arguments are exclusive'
    end
  else
    puts opts.help
    exit 0
  end

  begin
    printer = printer_class.new(upper, param)
    if source.kind_of?(ReVIEW::Book::Part)
      printer.print_part source
    else
      printer.print_book source
    end
  rescue ReVIEW::Error, Errno::ENOENT => err
    raise if $DEBUG
    error_exit err.message
  end
end

def error_exit(msg)
  $stderr.puts "#{File.basename($0)}: #{msg}"
  exit 1
end

main
