class FluentPluginGenerator

def self.lookup_license(license)

def self.lookup_license(license)
  LICENSE_REGISTRY.lookup(license)
end

def self.register_license(license, klass)

def self.register_license(license, klass)
  LICENSE_REGISTRY.register(license, klass)
end

def call

def call
  parse_options!
  FileUtils.mkdir_p(gem_name)
  Dir.chdir(gem_name) do
    copy_license
    template_directory.find do |path|
      next if path.directory?
      dest_dir = path.dirname.sub(/\A#{Regexp.quote(template_directory.to_s)}\/?/, "")
      dest_file = dest_filename(path)
      if path.extname == ".erb"
        if path.fnmatch?("*/plugin/*")
          next unless path.basename.fnmatch?("*#{type}*")
        end
        template(path, dest_dir + dest_file)
      else
        file(path, dest_dir + dest_file)
      end
    end
    pid = spawn("git", "init", ".")
    Process.wait(pid)
  end
end

def capitalized_name

def capitalized_name
  @capitalized_name ||= name.split(/[-_]/).map(&:capitalize).join
end

def class_name

def class_name
  "#{capitalized_name}#{type.capitalize}"
end

def copy_license

def copy_license
  # in gem_name directory
  return unless license_name
  puts "License: #{license_name}"
  license_class = self.class.lookup_license(license_name)
  @license = license_class.new
  Pathname("LICENSE").write(@license.text) unless @license.text.empty?
rescue Fluent::ConfigError
  usage("Unknown license: #{license_name}")
rescue => ex
  usage("#{ex.class}: #{ex.message}")
end

def create_label(dest, contents)

def create_label(dest, contents)
  if dest.exist?
    if dest.read == contents
      "identical"
    else
      "conflict"
    end
  else
    "create"
  end
end

def dash_name

def dash_name
  @dash_name ||= name.tr("_", "-")
end

def dest_filename(path)

def dest_filename(path)
  case path.to_s
  when %r!\.gemspec!
    "#{gem_name}.gemspec"
  when %r!lib/fluent/plugin!
    plugin_filename
  when %r!test/plugin!
    test_filename
  else
    path.basename.sub_ext("")
  end
end

def file(source, dest)

def file(source, dest)
  label = create_label(dest, source.read)
  puts "\t#{label} #{dest}"
  if label == "conflict"
    return unless overwrite?(dest)
  end
  FileUtils.cp(source, dest)
end

def gem_name

def gem_name
  "fluent-plugin-#{dash_name}"
end

def initialize(argv = ARGV)

def initialize(argv = ARGV)
  @argv = argv
  @parser = prepare_parser
  @license_name = "Apache-2.0"
  @overwrite_all = false
end

def overwrite?(dest)

def overwrite?(dest)
  return true if @overwrite_all
  loop do
    print "Overwrite #{dest}? (enter \"h\" for help) [Ynaqh]"
    answer = $stdin.gets.chomp
    return true if /\Ay\z/i =~ answer || answer.empty?
    case answer
    when "n"
      return false
    when "a"
      @overwrite_all = true
      return true
    when "q"
      exit
    when "h"
      puts <<HELP
Y - yes, overwrite
n - no, do not overwrite
a - all, overwrite this and all others
q - quit, abort
h - help, show this help
LP
    end
    puts "Retrying..."
  end
end

def parse_options!

def parse_options!
  @parser.parse!(@argv)
  unless @argv.size == 2
    raise ArgumentError, "Missing arguments"
  end
  @type, @name = @argv
rescue => e
  usage("#{e.class}:#{e.message}")
end

def plugin_filename

def plugin_filename
  case type
  when "input"
    "in_#{underscore_name}.rb"
  when "output"
    "out_#{underscore_name}.rb"
  else
    "#{type}_#{underscore_name}.rb"
  end
end

def plugin_name

def plugin_name
  underscore_name
end

def preamble

def preamble
  @license.preamble(user_name)
end

def prepare_parser

def prepare_parser
  @parser = OptionParser.new
  @parser.version = Fluent::VERSION
  @parser.banner = <<BANNER
age: fluent-plugin-generate [options] <type> <name>
nerate a project skeleton for creating a Fluentd plugin
guments:
type: #{SUPPORTED_TYPES.join(",")}
name: Your plugin name
tions:
NNER
  @parser.on("--[no-]license=NAME", "Specify license name (default: Apache-2.0)") do |v|
    @license_name = v || "no-license"
  end
  @parser
end

def template(source, dest)

def template(source, dest)
  dest.dirname.mkpath
  contents =
    if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
      ERB.new(source.read, trim_mode: "-")
    else
      ERB.new(source.read, nil, "-")
    end.result(binding)
  label = create_label(dest, contents)
  puts "\t#{label} #{dest}"
  if label == "conflict"
    return unless overwrite?(dest)
  end
  File.write(dest, contents)
end

def template_directory

def template_directory
  (Pathname(__dir__) + "../../../templates/new_gem").realpath
end

def template_file(filename)

def template_file(filename)
  template_directory + filename
end

def test_filename

def test_filename
  case type
  when "input"
    "test_in_#{underscore_name}.rb"
  when "output"
    "test_out_#{underscore_name}.rb"
  else
    "test_#{type}_#{underscore_name}.rb"
  end
end

def underscore_name

def underscore_name
  @underscore_name ||= name.tr("-", "_")
end

def usage(message = "")

def usage(message = "")
  puts message
  puts
  puts @parser.help
  exit(false)
end

def user_email

def user_email
  v = `git config --get user.email`.chomp
  v.empty? ? "TODO: Write your email" : v
end

def user_name

def user_name
  v = `git config --get user.name`.chomp
  v.empty? ? "TODO: Write your name" : v
end