#!/usr/bin/ruby
#
# Copyright (c) 2014-2017 Masanori Kado, 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".
#
# Convert old PREDEF/CHAPS/PART/POSTDEF files into catalog.yml.

require 'pathname'
require 'optparse'
bindir = Pathname.new(__FILE__).realpath.dirname
$LOAD_PATH.unshift((bindir + '../lib').realpath)
require 'review/version'
require 'review/extentions'
require 'review/logger'

def main
  @logger = ReVIEW.logger
  opts = OptionParser.new
  opts.version = ReVIEW::VERSION
  opts.banner = "Usage: #{File.basename($PROGRAM_NAME)} dirname"
  opts.on('-h', '--help', 'print this message and quit.') do
    puts opts.help
    exit 0
  end

  begin
    opts.parse!
  rescue OptionParser::ParseError => err
    @logger.error err.message
    $stderr.puts opts.help
    exit 1
  end

  dir = Dir.pwd

  # confirmation
  if File.exist?("#{dir}/catalog.yml")
    loop do
      print 'The catalog.yml already exists. Do you want to overwrite it? [y/n]'
      case gets
      when /\A[yY]/
        @logger.info 'Start writing...'
        break
      when /\A[nN]/, /\A\Z/
        @logger.info 'bye.'
        exit
      end
    end
  end

  File.open("#{dir}/catalog.yml", 'w') do |catalog|
    # predef
    if File.exist?("#{dir}/PREDEF")
      catalog << parse_predef(File.open("#{dir}/PREDEF").read)
    end
    # chaps and parts
    if File.exist?("#{dir}/CHAPS")
      if File.exist?("#{dir}/PART")
        catalog << parse_parts(File.open("#{dir}/PART").read,
                               File.open("#{dir}/CHAPS").read)
      else
        catalog << parse_chaps(File.open("#{dir}/CHAPS").read)
      end
    end
    # postdef
    if File.exist?("#{dir}/POSTDEF")
      postdef = File.open("#{dir}/POSTDEF").read
      loop do
        print 'Do you want to convert POSTDEF into APPENDIX? [y/n]'
        case gets
        when /\A[yY]/
          catalog << parse_postdef(postdef, true)
          break
        when /\A[nN]/, /\A\Z/
          catalog << parse_postdef(postdef)
          break
        end
      end
    end
  end

  puts File.open("#{dir}/catalog.yml").read
end

def parse_internal(str, header)
  if str.present?
    header + str.split("\n").map { |i| "  - #{i}\n" }.join
  else
    header
  end
end

def parse_predef(str)
  header = "PREDEF:\n"
  parse_internal(str, header) + "\n"
end

def parse_chaps(str)
  header = "CHAPS:\n"
  parse_internal(str, header) + "\n"
end

def parse_postdef(str, to_appendix = false)
  if to_appendix
    header = "APPENDIX:\n"
  else
    header = "POSTDEF:\n"
  end
  parse_internal(str, header) + "\n"
end

def parse_parts(parts_str, chaps_str)
  return "CHAPS:\n\n" if parts_str.blank? or chaps_str.blank?

  parts = parts_str.split("\n")
  chaps = chaps_str.split("\n\n")
  "CHAPS:\n" + parts.zip(chaps).map { |k, vs| "  - #{k}:\n" + vs.split("\n").map { |i| "    - #{i}\n" }.join }.join + "\n"
end

main if File.basename($PROGRAM_NAME) == File.basename(__FILE__)
