#!/usr/bin/env ruby
# frozen_string_literal: true

require 'optparse'
require 'ostruct'

require_relative '../lib/markly'

def parse_options
  options = OpenStruct.new
  extensions = Markly.extensions
  parse_flags = Markly::PARSE_FLAGS
  render_flags = Markly::RENDER_FLAGS

  options.active_extensions = []
  options.active_parse_flags = Markly::DEFAULT
  options.active_render_flags = Markly::DEFAULT

  option_parser = OptionParser.new do |opts|
    opts.banner = 'Usage: markly [--html-renderer] [--extension=EXTENSION]'
    opts.separator '                    [--parse-option=OPTION]'
    opts.separator '                    [--render-option=OPTION]'
    opts.separator '                    [FILE..]'
    opts.separator ''
    opts.separator 'Convert one or more CommonMark files to HTML and write to standard output.'
    opts.separator 'If no FILE argument is provided, text will be read from STDIN.'
    opts.separator ''

    opts.on('--extension=EXTENSION', Array, 'Use EXTENSION for parsing and HTML output (unless --html-renderer is specified)') do |values|
      values.each do |value|
        if extensions.include?(value)
          options.active_extensions << value.to_sym
        else
          abort("extension '#{value}' not found")
        end
      end
    end

    opts.on('-h', '--help', 'Prints this help') do
      puts opts
      puts
      puts "Available extentions: #{extensions.join(', ')}"
      puts "Available parse flags: #{parser_flags.keys.join(', ')}"
      puts "Available render flags: #{render_flags.keys.join(', ')}"
      puts
      puts 'See the README for more information on these.'
      exit
    end

    opts.on('--html-renderer', 'Use the HtmlRenderer renderer rather than the native C renderer') do
      options.renderer = true
    end

    opts.on('--parse-option=OPTION', Array, 'OPTION passed during parsing') do |values|
      values.each do |value|active_parser_flags
        if parser_flags.key?(value.to_sym)
          options.active_parser_flags << value.to_sym
        else
          abort("parse-option '#{value}' not found")
        end
      end
    end

    opts.on('--render-option=OPTION', Array, 'OPTION passed during rendering') do |values|
      values.each do |value|
        if render_flags.key?(value.to_sym)
          options.active_render_flags << value.to_sym
        else
          abort("render-option '#{value}' not found")
        end
      end
    end

    opts.on('-v', '--version', 'Version information') do
      puts "markly #{Markly::VERSION}"
      exit
    end
  end

  option_parser.parse!

  options
end

options = parse_options

doc = Markly.parse(ARGF.read, flags: options.active_parse_flags, extensions: options.active_extensions)

if options.renderer
  renderer = Markly::HtmlRenderer.new(extensions: options.active_extensions)
  STDOUT.write(renderer.render(doc))
else
  STDOUT.write(doc.to_html(flags: options.active_render_flags, extensions: options.active_extensions))
end
