class RuboCop::Plugin::Loader

@api private
A class for loading and resolving plugins.

def constantize(plugin_name, plugin_config)

rubocop:enable Metrics/MethodLength
def constantize(plugin_name, plugin_config)
  require_plugin(plugin_config['require_path'])
  if (constant_name = plugin_config['plugin_class_name'])
    begin
      Kernel.const_get(constant_name)
    rescue StandardError
      raise <<~MESSAGE
        Failed while configuring plugin `#{plugin_name}': no constant with name `#{constant_name}' was found.
      MESSAGE
    end
  else
    constantize_plugin_from_gemspec_metadata(plugin_name)
  end
end

def constantize_plugin_from(plugin_name, plugin_config)

def constantize_plugin_from(plugin_name, plugin_config)
  if plugin_name.is_a?(String) || plugin_name.is_a?(Symbol)
    constantize(plugin_name, plugin_config)
  else
    plugin_name
  end
end

def constantize_plugin_from_gemspec_metadata(plugin_name)

def constantize_plugin_from_gemspec_metadata(plugin_name)
  plugin_class_name = Gem.loaded_specs[plugin_name].metadata['default_lint_roller_plugin']
  Kernel.const_get(plugin_class_name)
rescue LoadError, StandardError
  raise Plugin::LoadError, plugin_name
end

def load(plugins)

def load(plugins)
  normalized_plugin_configs = normalize(plugins)
  normalized_plugin_configs.filter_map do |plugin_name, plugin_config|
    next unless plugin_config['enabled']
    plugin_class = constantize_plugin_from(plugin_name, plugin_config)
    plugin_class.new(plugin_config)
  end
end

def normalize(plugin_configs)

rubocop:disable Metrics/MethodLength
def normalize(plugin_configs)
  plugin_configs.to_h do |plugin_config|
    if plugin_config == Plugin::OBSOLETE_INTERNAL_AFFAIRS_PLUGIN_NAME
      warn Rainbow(<<~MESSAGE).yellow
        Specify `rubocop-internal_affairs` instead of `rubocop/cop/internal_affairs` in your configuration.
      MESSAGE
      plugin_config = Plugin::INTERNAL_AFFAIRS_PLUGIN_NAME
    end
    if plugin_config.is_a?(Hash)
      plugin_name = plugin_config.keys.first
      [
        plugin_name, DEFAULT_PLUGIN_CONFIG.merge(
          { 'require_path' => plugin_name }, plugin_config.values.first
        )
      ]
    # NOTE: Compatibility is maintained when `require: rubocop/cop/internal_affairs` remains
    # specified in `.rubocop.yml`.
    elsif (builtin_plugin_config = Plugin::BUILTIN_INTERNAL_PLUGINS[plugin_config])
      [plugin_config, builtin_plugin_config]
    else
      [plugin_config, DEFAULT_PLUGIN_CONFIG.merge('require_path' => plugin_config)]
    end
  end
end

def require_plugin(require_path)

def require_plugin(require_path)
  FeatureLoader.load(config_directory_path: Dir.pwd, feature: require_path)
end