<commit_before># frozen_string_literal: true

module Wardrobe
  class DefaultSettersStore < Store
    def initialize
      super({setter: Wardrobe.setters[:setter]})
    end
  end

  class DefaultGettersStore < Store
    def initialize
      super({getter: Wardrobe.getters[:getter]})
    end
  end

  class Config
    def self.registered_stores
      @registered_stores ||= {}.freeze
    end

    def self.register_store(name, klass)
      @registered_stores = registered_stores.merge(name => klass).freeze
    end

    register_store(:attribute_store, AttributeStore)
    register_store(:plugin_store, PluginStore)
    register_store(:option_store, OptionStore)
    register_store(:default_setters_store, DefaultSettersStore)
    register_store(:default_getters_store, DefaultGettersStore)

    attr_reader :stores, :instance_methods_module, :class_methods_module

    def initialize
      @stores = {}.freeze
      @instance_methods_module = Module.new.freeze
      @class_methods_module = Module.new.freeze
      self.class.registered_stores.each do |key, value|
        add_store(key, value, initializer: true)
      end
      freeze
    end

    def merge_wardrobe_config(other_wardrobe_config)
      @wardrobe_config = wardrobe_config.merge(other_wardrobe_config, self)
    end

    def self.create_and_add_to(object, merge_with: nil)
      config = new
      config = config.merge(merge_with, object) if merge_with
      object.instance_variable_set(:@wardrobe_config, config)
    end

    def add_instance_methods(klass, &blk)
      update do
        @instance_methods_module = instance_methods_module.dup
        instance_methods_module.class_exec(&blk)
        instance_methods_module.freeze
        klass.include(instance_methods_module)
      end
    end

    def add_class_methods(klass, &blk)
      update do
        @class_methods_module = class_methods_module.dup
        class_methods_module.class_exec(&blk)
        class_methods_module.freeze
        klass.extend(class_methods_module)
      end
    end

    def update(&blk)
      if frozen?
        dup.update(&blk)
      else
        instance_exec(&blk)
        freeze
      end
    end

    def add_store(name, klass, initializer: false)
      if frozen?
        dup.add_store(name, klass)
      else
        @stores = stores.merge(name => klass)
        instance_variable_set("@#{name}", klass.new)
        define_singleton_method(name) { instance_variable_get("@#{name}") }
        freeze unless initializer
      end
    end

    def merge(other, calling_object)
      if frozen?
        dup.merge(other, calling_object)
      else
        (other.stores.keys - stores.keys).each do |name|
          add_store(name, other.stores[name], initializer: true)
        end
        stores.each do |name, klass|
          instance = respond_to?(name) ? send(name) : klass.new
          instance_variable_set(
            "@#{name}", instance.merge(other.send(name), calling_object, self)
          )<commit_msg>Skip store morge if other does not have store<commit_after># frozen_string_literal: true

module Wardrobe
  class DefaultSettersStore < Store
    def initialize
      super({setter: Wardrobe.setters[:setter]})
    end
  end

  class DefaultGettersStore < Store
    def initialize
      super({getter: Wardrobe.getters[:getter]})
    end
  end

  class Config
    def self.registered_stores
      @registered_stores ||= {}.freeze
    end

    def self.register_store(name, klass)
      @registered_stores = registered_stores.merge(name => klass).freeze
    end

    register_store(:attribute_store, AttributeStore)
    register_store(:plugin_store, PluginStore)
    register_store(:option_store, OptionStore)
    register_store(:default_setters_store, DefaultSettersStore)
    register_store(:default_getters_store, DefaultGettersStore)

    attr_reader :stores, :instance_methods_module, :class_methods_module

    def initialize
      @stores = {}.freeze
      @instance_methods_module = Module.new.freeze
      @class_methods_module = Module.new.freeze
      self.class.registered_stores.each do |key, value|
        add_store(key, value, initializer: true)
      end
      freeze
    end

    def merge_wardrobe_config(other_wardrobe_config)
      @wardrobe_config = wardrobe_config.merge(other_wardrobe_config, self)
    end

    def self.create_and_add_to(object, merge_with: nil)
      config = new
      config = config.merge(merge_with, object) if merge_with
      object.instance_variable_set(:@wardrobe_config, config)
    end

    def add_instance_methods(klass, &blk)
      update do
        @instance_methods_module = instance_methods_module.dup
        instance_methods_module.class_exec(&blk)
        instance_methods_module.freeze
        klass.include(instance_methods_module)
      end
    end

    def add_class_methods(klass, &blk)
      update do
        @class_methods_module = class_methods_module.dup
        class_methods_module.class_exec(&blk)
        class_methods_module.freeze
        klass.extend(class_methods_module)
      end
    end

    def update(&blk)
      if frozen?
        dup.update(&blk)
      else
        instance_exec(&blk)
        freeze
      end
    end

    def add_store(name, klass, initializer: false)
      if frozen?
        dup.add_store(name, klass)
      else
        @stores = stores.merge(name => klass)
        instance_variable_set("@#{name}", klass.new)
        define_singleton_method(name) { instance_variable_get("@#{name}") }
        freeze unless initializer
      end
    end

    def merge(other, calling_object)
      if frozen?
        dup.merge(other, calling_object)
      else
        (other.stores.keys - stores.keys).each do |name|
          add_store(name, other.stores[name], initializer: true)
        end
        stores.each do |name, klass|
          next unless other.respond_to?(name)
          instance = respond_to?(name) ? send(name) : klass.new
          instance_variable_set(
            "@#{name}", instance.merge(other.send(name), calling_object, self)
          )
{'fraction_non_alphanumeric': 0.08482438701126574, 'fraction_numerical': 0.0, 'mean_word_length': 2.938030006523157, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '623372', 'n_tokens_mistral': 1818, 'n_tokens_neox': 1823, 'n_words': 363}