class Standard::Plugin::MergesPluginsIntoRubocopConfig

def all_cop_keys_previously_configured_by_plugins(options_config, permit_merging:)

def all_cop_keys_previously_configured_by_plugins(options_config, permit_merging:)
  if permit_merging
    []
  else
    Array(options_config["AllCops"]&.keys) - RuboCop::ConfigLoader.default_configuration["AllCops"].keys
  end
end

def blank_rubocop_config(example_config)

def blank_rubocop_config(example_config)
  RuboCop::Config.new(example_config.to_h.slice(*MANDATORY_RUBOCOP_CONFIG_KEYS), "")
end

def call(options_config, standard_config, plugins, permit_merging:)

def call(options_config, standard_config, plugins, permit_merging:)
  runner_context = @creates_runner_context.call(standard_config)
  plugin_config = combine_rubocop_configs(options_config, runner_context, plugins, permit_merging: permit_merging).to_h
  merge_config_into_all_cops!(options_config, plugin_config)
  merge_config_into_standard!(options_config, plugin_config, permit_merging: permit_merging)
end

def combine_rubocop_configs(options_config, runner_context, plugins, permit_merging:)

def combine_rubocop_configs(options_config, runner_context, plugins, permit_merging:)
  all_cop_keys_configured_by_plugins = all_cop_keys_previously_configured_by_plugins(options_config, permit_merging: permit_merging)
  fake_out_rubocop_default_configuration(options_config) do |fake_config|
    plugins.reduce(fake_config) do |combined_config, plugin|
      RuboCop::ConfigLoader.instance_variable_set(:@default_configuration, combined_config)
      next_config, path = config_for_plugin(plugin, runner_context)
      next_config["AllCops"], all_cop_keys_configured_by_plugins = merge_all_cop_settings(
        combined_config["AllCops"],
        next_config["AllCops"],
        all_cop_keys_configured_by_plugins
      )
      delete_already_configured_keys!(combined_config.keys, next_config, dont_delete_keys: ["AllCops"])
      RuboCop::ConfigLoader.merge_with_default(next_config, path, unset_nil: false)
    end
  end
end

def config_for_plugin(plugin, runner_context)

def config_for_plugin(plugin, runner_context)
  rules = plugin.rules(runner_context)
  if rules.type == :path
    [RuboCop::ConfigLoader.load_file(rules.value), rules.value]
  elsif rules.type == :object
    path = plugin.method(:rules).source_location[0]
    [RuboCop::Config.create(rules.value, path, check: true), path]
  elsif rules.type == :error
    raise "Plugin `#{plugin.about&.name || plugin.inspect}' failed to load with error: #{rules.value.respond_to?(:message) ? rules.value.message : rules.value}"
  end
end

def delete_already_configured_keys!(configured_keys, next_config, dont_delete_keys: [])

def delete_already_configured_keys!(configured_keys, next_config, dont_delete_keys: [])
  duplicate_keys = configured_keys & Array(next_config&.keys)
  (duplicate_keys - dont_delete_keys).each do |key|
    next_config.delete(key)
  end
end

def except(hash_or_config, keys)

def except(hash_or_config, keys)
  hash_or_config.to_h.except(*keys).to_h
end

def fake_out_rubocop_default_configuration(options_config)

def fake_out_rubocop_default_configuration(options_config)
  og_default_config = RuboCop::ConfigLoader.default_configuration
  set_target_rails_version_on_all_cops_because_its_technically_not_allowed!(options_config)
  result = yield blank_rubocop_config(options_config)
  RuboCop::ConfigLoader.instance_variable_set(:@default_configuration, og_default_config)
  result
end

def initialize

def initialize
  @creates_runner_context = Standard::Plugin::CreatesRunnerContext.new
end

def merge(old_hash, new_hash)

https://github.com/rubocop/rubocop/blob/v1.48.1/lib/rubocop/config_loader_resolver.rb#L98
This is a simplified version of rubocop's ConfigLoader#merge:
Always deletes nil entries, always overwrites arrays
def merge(old_hash, new_hash)
  result = old_hash.merge(new_hash)
  keys_appearing_in_both = old_hash.keys & new_hash.keys
  keys_appearing_in_both.each do |key|
    if new_hash[key].nil?
      result.delete(key)
    elsif old_hash[key].is_a?(Hash) && new_hash[key].is_a?(Hash)
      result[key] = merge(old_hash[key], new_hash[key])
    end
  end
  result
end

def merge_all_cop_settings(existing_all_cops, new_all_cops, already_configured_keys)

Exclude paths and patterns.
new`) to allow plugins to add to the array, for example Include and
overwrite the AllCops defaults but rather munge the arrays (`existing |
The one exception to this are array fields, because we don't want to

have exclusive first-in-wins rights to that setting.
set by RuboCop's default configuration, but once a plugin sets an AllCop setting, they
This is how we ensure "first-in wins": plugins can override AllCops settings that are
def merge_all_cop_settings(existing_all_cops, new_all_cops, already_configured_keys)
  return [existing_all_cops, already_configured_keys] unless new_all_cops.is_a?(Hash)
  combined_all_cops = existing_all_cops.dup
  combined_configured_keys = already_configured_keys.dup
  new_all_cops.each do |key, value|
    if combined_all_cops[key].is_a?(Array) && value.is_a?(Array)
      combined_all_cops[key] |= value
      combined_configured_keys |= [key]
    elsif !combined_configured_keys.include?(key)
      combined_all_cops[key] = value
      combined_configured_keys << key
    end
  end
  [combined_all_cops, combined_configured_keys]
end

def merge_config_into_all_cops!(options_config, plugin_config)

def merge_config_into_all_cops!(options_config, plugin_config)
  options_config["AllCops"].merge!(
    except(plugin_config["AllCops"], DISALLOWED_ALLCOPS_KEYS)
  )
end

def merge_config_into_standard!(options_config, plugin_config, permit_merging:)

def merge_config_into_standard!(options_config, plugin_config, permit_merging:)
  if permit_merging
    plugin_config.each do |key, value|
      options_config[key] = if options_config[key].is_a?(Hash)
        merge(options_config[key], value)
      else
        value
      end
    end
  else
    except(plugin_config, options_config.keys).each do |key, value|
      options_config[key] = value
    end
  end
end

def set_target_rails_version_on_all_cops_because_its_technically_not_allowed!(options_config)

See: https://github.com/rubocop/rubocop/pull/11833

because it's not a default AllCops key specified in RuboCop's embedded default config.
Avoid a warning that would otherwise be emitted by any plugin that set TargetRailsVersion
def set_target_rails_version_on_all_cops_because_its_technically_not_allowed!(options_config)
  return if !options_config.key?("AllCops") || options_config["AllCops"].key?("TargetRailsVersion")
  options_config["AllCops"]["TargetRailsVersion"] = nil
end