class Embulk::PluginManager

def get_guess(type)

def get_guess(type)
  lookup(:guess, type)
end

def initialize

def initialize
  @registries = {}
  %w[input output parser formatter decoder encoder line_filter filter guess executor].each do |category|
    @registries[category.to_sym] = PluginRegistry.new(category, "embulk/#{category}/")
  end
end

def lookup(category, type)

def lookup(category, type)
  @registries[category].lookup(type)
end

def new_java_decoder(type)

def new_java_decoder(type)
  lookup(:decoder, type).new_java
end

def new_java_encoder(type)

def new_java_encoder(type)
  lookup(:encoder, type).new_java
end

def new_java_executor(type)

def new_java_executor(type)
  lookup(:executor, type).new_java
end

def new_java_filter(type)

def new_java_filter(type)
  lookup(:filter, type).new_java
end

def new_java_formatter(type)

def new_java_formatter(type)
  lookup(:formatter, type).new_java
end

def new_java_guess(type)

def new_java_guess(type)
  lookup(:guess, type).new_java
end

def new_java_input(type)

def new_java_input(type)
  lookup(:input, type).new_java
end

def new_java_output(type)

def new_java_output(type)
  lookup(:output, type).new_java
end

def new_java_parser(type)

def new_java_parser(type)
  lookup(:parser, type).new_java
end

def register_filter(type, klass)

def register_filter(type, klass)
  register_plugin(:filter, type, klass, FilterPlugin)
end

def register_formatter(type, klass)

def register_formatter(type, klass)
  register_plugin(:formatter, type, klass, FormatterPlugin)
end

def register_guess(type, klass)

def register_guess(type, klass)
  register_plugin(:guess, type, klass, GuessPlugin,
                 "Guess plugin #{klass} must extend GuessPlugin, LineGuessPlugin, or TextGuessPlugin class")
end

def register_input(type, klass)

def register_input(type, klass)
  register_plugin(:input, type, klass, InputPlugin)
end

def register_java_decoder(type, klass)

def register_java_decoder(type, klass)
  register_java_plugin(:decoder, type, klass,
                       "org.embulk.spi.DecoderPlugin" => DecoderPlugin)
end

def register_java_encoder(type, klass)

def register_java_encoder(type, klass)
  register_java_plugin(:encoder, type, klass,
                       "org.embulk.spi.EncoderPlugin" => EncoderPlugin)
end

def register_java_executor(type, klass)

def register_java_executor(type, klass)
  register_java_plugin(:executor, type, klass,
                       "org.embulk.spi.ExecutorPlugin" => ExecutorPlugin)
end

def register_java_filter(type, klass)

def register_java_filter(type, klass)
  register_java_plugin(:filter, type, klass,
                       "org.embulk.spi.FilterPlugin" => FilterPlugin)
end

def register_java_formatter(type, klass)

def register_java_formatter(type, klass)
  register_java_plugin(:formatter, type, klass,
                       "org.embulk.spi.FormatterPlugin" => FormatterPlugin)
end

def register_java_guess(type, klass)

def register_java_guess(type, klass)
  register_java_plugin(:guess, type, klass,
                       "org.embulk.spi.GuessPlugin" => GuessPlugin)
end

def register_java_input(type, klass)

def register_java_input(type, klass)
  register_java_plugin(:input, type, klass,
                       "org.embulk.spi.InputPlugin" => InputPlugin,
                       "org.embulk.spi.FileInputPlugin" => FileInputPlugin)
end

def register_java_output(type, klass)

def register_java_output(type, klass)
  register_java_plugin(:output, type, klass,
                       "org.embulk.spi.OutputPlugin" => OutputPlugin,
                       "org.embulk.spi.FileOutputPlugin" => FileOutputPlugin)
end

def register_java_parser(type, klass)

def register_java_parser(type, klass)
  register_java_plugin(:parser, type, klass,
                       "org.embulk.spi.ParserPlugin" => ParserPlugin)
end

def register_java_plugin(category, type, klass, iface_map, message=nil)

def register_java_plugin(category, type, klass, iface_map, message=nil)
  found = iface_map.find do |iface_name,ruby_base_class|
    iface = JRuby.runtime.getJRubyClassLoader.load_class(iface_name)
    iface.isAssignableFrom(klass)
  end
  unless found
    message ||= "Java plugin #{klass} must implement #{iface_map.keys.join(' or ')}"
    raise message
  end
  adapted = found.last.from_java(klass)
  @registries[category].register(type, adapted)
end

def register_output(type, klass)

def register_output(type, klass)
  register_plugin(:output, type, klass, OutputPlugin,
                  "Output plugin #{klass} must extend OutputPlugin")
end

def register_parser(type, klass)

def register_parser(type, klass)
  register_plugin(:parser, type, klass, ParserPlugin)
end

def register_plugin(category, type, klass, base_class, message=nil)

def register_plugin(category, type, klass, base_class, message=nil)
  unless klass < base_class
    message ||= "Plugin #{klass} must inherit #{base_class}"
    raise message
  end
  @registries[category].register(type, klass)
end