<commit_before>module HipaaCrypt
  class MultiEncryptor

    attr_reader :merged_options, :encryptors

    def initialize( options = {} )
      @merged_options = merge_defaults(options)
      merged_options[:encryptor] ||= HipaaCrypt::Encryptor
      @encryptors = build_encryptors
    end

    def merge_defaults(options)
      default_options = HipaaCrypt.config.except(:encryptor).deep_merge(options)
      local_defaults  = default_options.except :defaults
      local_defaults.deep_merge!( default_options.fetch :defaults, {})
    end

    def build_encryptors
      chain = merged_options[:chain] || []
      all_options = ([merged_options] + chain.map {|opts| merged_options.deep_merge(opts) }).uniq
      all_options.map { |opts| opts.delete(:encryptor) { HipaaCrypt::Encryptor }.new(opts) }
    end

    def encrypt(*args)
      encryptors.first.send :encrypt, *args
    end

    def decrypt(*args)
      enkryptors = encryptors.dup
      value = nil
      until value
        begin
          value = enkryptors.shift.send :decrypt, *args
        rescue HipaaCrypt::Error::OpenSSLCipherCipherError => e
          retry unless enkryptors.empty?
          raise e
        end
      end
      value
    end
  end
end<commit_msg>#merge_defaults<commit_after>module HipaaCrypt
  class MultiEncryptor

    attr_reader :merged_options, :encryptors

    def initialize( options = {} )
      @merged_options = merge_defaults(options)
      @merged_options[:encryptor] = HipaaCrypt::Encryptor if @merged_options[:encryptor] == self.class
      @encryptors = build_encryptors
    end

    def merge_defaults(options)
      default_options = HipaaCrypt.config.deep_merge(options)
      local_defaults  = default_options.except :defaults
      local_defaults.deep_merge!( default_options.fetch :defaults, {} )
    end

    def build_encryptors
      chain = merged_options[:chain] || []
      all_options = ([merged_options] + chain.map {|opts| merged_options.deep_merge(opts) }).uniq
      all_options.map { |opts| opts.delete(:encryptor) { HipaaCrypt::Encryptor }.new(opts) }
    end

    def encrypt(*args)
      encryptors.first.send :encrypt, *args
    end

    def decrypt(*args)
      encryptors = self.encryptors.dup
      value = nil
      until value
        begin
          value = encryptors.shift.send :decrypt, *args
        rescue HipaaCrypt::Error::OpenSSLCipherCipherError => e
          retry unless encryptors.empty?
          raise e
        end
      end
      value
    end
  end
end
{'fraction_non_alphanumeric': 0.093562574970012, 'fraction_numerical': 0.0, 'mean_word_length': 2.940157480314961, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '5812005', 'n_tokens_mistral': 800, 'n_tokens_neox': 757, 'n_words': 156}