class SplitIoClient::Cache::Repositories::SplitsRepository

def add_feature_flag(split)

def add_feature_flag(split)
  return unless split[:name]
  existing_split = get_split(split[:name])
  if(!existing_split)
    increase_tt_name_count(split[:trafficTypeName])
  elsif(existing_split[:trafficTypeName] != split[:trafficTypeName])
    increase_tt_name_count(split[:trafficTypeName])
    decrease_tt_name_count(existing_split[:trafficTypeName])
    remove_from_flag_sets(existing_split)
  elsif(existing_split[:sets] != split[:sets])
    remove_from_flag_sets(existing_split)
  end
  if !split[:sets].nil?
    for flag_set in split[:sets]
      if !@flag_sets.flag_set_exist?(flag_set)
        if @flag_set_filter.should_filter?
          next
        end
        @flag_sets.add_flag_set(flag_set)
      end
      @flag_sets.add_feature_flag_to_flag_set(flag_set, split[:name])
    end
  end
  @adapter.set_string(namespace_key(".split.#{split[:name]}"), split.to_json)
end

def clear

def clear
  @tt_cache.clear
  @adapter.clear(namespace_key)
end

def decrease_tt_name_count(tt_name)

def decrease_tt_name_count(tt_name)
  return unless tt_name
  @tt_cache[tt_name] -= 1 if @tt_cache[tt_name]
  @tt_cache.delete(tt_name) if @tt_cache[tt_name] == 0
end

def exists?(name)

def exists?(name)
  @adapter.exists?(namespace_key(".split.#{name}"))
end

def flag_set_filter

def flag_set_filter
  @flag_set_filter
end

def get_change_number

def get_change_number
  @adapter.string(namespace_key('.splits.till'))
end

def get_feature_flags_by_sets(flag_sets)

def get_feature_flags_by_sets(flag_sets)
  sets_to_fetch = Array.new
  flag_sets.each do |flag_set|
    unless @flag_sets.flag_set_exist?(flag_set)
      @config.logger.warn("Flag set #{flag_set} is not part of the configured flag set list, ignoring it.")
      next
    end
    sets_to_fetch.push(flag_set)
  end
  @flag_sets.get_flag_sets(flag_sets)
end

def get_split(name)

def get_split(name)
  split = @adapter.string(namespace_key(".split.#{name}"))
  JSON.parse(split, symbolize_names: true) if split
end

def get_splits(names, symbolize_names = true)

def get_splits(names, symbolize_names = true)
  splits = {}
  split_names = names.map { |name| namespace_key(".split.#{name}") }
  splits.merge!(
    @adapter
      .multiple_strings(split_names)
      .map { |name, data| [name.gsub(namespace_key('.split.'), ''), data] }.to_h
  )
  splits.map do |name, data|
    parsed_data = data ? JSON.parse(data, symbolize_names: true) : nil
    split_name = symbolize_names ? name.to_sym : name
    [split_name, parsed_data]
  end.to_h
end

def increase_tt_name_count(tt_name)

def increase_tt_name_count(tt_name)
  return unless tt_name
  @tt_cache[tt_name] = 0 unless @tt_cache[tt_name]
  @tt_cache[tt_name] += 1
end

def initialize(config, flag_sets_repository, flag_set_filter)

def initialize(config, flag_sets_repository, flag_set_filter)
  super(config)
  @tt_cache = {}
  @adapter = case @config.cache_adapter.class.to_s
  when 'SplitIoClient::Cache::Adapters::RedisAdapter'
    SplitIoClient::Cache::Adapters::CacheAdapter.new(@config)
  else
    @config.cache_adapter
  end
  @flag_sets = flag_sets_repository
  @flag_set_filter = flag_set_filter
  unless @config.mode.equal?(:consumer)
    @adapter.set_string(namespace_key('.splits.till'), '-1')
    @adapter.initialize_map(namespace_key('.segments.registered'))
  end
end

def is_flag_set_exist(flag_set)

def is_flag_set_exist(flag_set)
  @flag_sets.flag_set_exist?(flag_set)
end

def kill(change_number, split_name, default_treatment)

def kill(change_number, split_name, default_treatment)
  split = get_split(split_name)
  return if split.nil?
  split[:killed] = true
  split[:defaultTreatment] = default_treatment
  split[:changeNumber] = change_number
  @adapter.set_string(namespace_key(".split.#{split_name}"), split.to_json)
end

def not_ready!

def not_ready!
  @adapter.set_string(namespace_key('.splits.ready'), -1)
end

def ready!

def ready!
  @adapter.set_string(namespace_key('.splits.ready'), Time.now.utc.to_i)
end

def ready?

def ready?
  @adapter.string(namespace_key('.splits.ready')).to_i != -1
end

def remove_feature_flag(split)

def remove_feature_flag(split)
  tt_name = split[:trafficTypeName]
  decrease_tt_name_count(split[:trafficTypeName])
  remove_from_flag_sets(split)
  @adapter.delete(namespace_key(".split.#{split[:name]}"))
end

def remove_from_flag_sets(feature_flag)

def remove_from_flag_sets(feature_flag)
  name = feature_flag[:name]
  flag_sets = get_split(name)[:sets] if exists?(name)
  if !flag_sets.nil?
    for flag_set in flag_sets
      @flag_sets.remove_feature_flag_from_flag_set(flag_set, feature_flag[:name])
      if is_flag_set_exist(flag_set) && @flag_sets.get_flag_sets([flag_set]).length == 0 && !@flag_set_filter.should_filter?
          @flag_sets.remove_flag_set(flag_set)
      end
    end
  end
end

def set_change_number(since)

def set_change_number(since)
  @adapter.set_string(namespace_key('.splits.till'), since)
end

def set_segment_names(names)

def set_segment_names(names)
  return if names.nil? || names.empty?
  names.each do |name|
    @adapter.add_to_set(namespace_key('.segments.registered'), name)
  end
end

def split_names

Return an array of Split Names excluding control keys like splits.till
def split_names
  @adapter.find_strings_by_prefix(namespace_key('.split.'))
    .map { |split| split.gsub(namespace_key('.split.'), '') }
end

def splits(filtered_names=nil)

def splits(filtered_names=nil)
  symbolize = true
  if filtered_names.nil?
    filtered_names = split_names
    symbolize = false
  end
  get_splits(filtered_names, symbolize)
end

def splits_count

def splits_count
  split_names.length
end

def traffic_type_exists(tt_name)

def traffic_type_exists(tt_name)
  case @adapter
  when SplitIoClient::Cache::Adapters::CacheAdapter
    tt_count = @adapter.string(namespace_key(".trafficType.#{tt_name}"))
    begin
      !tt_count.nil? && Integer(tt_count, 10) > 0
    rescue StandardError => e
      @config.logger.error("Error while parsing Traffic Type count: #{e.message}")
      false
    end
  else
    @tt_cache.key?(tt_name) && @tt_cache[tt_name] > 0
  end
end

def update(to_add, to_delete, new_change_number)

def update(to_add, to_delete, new_change_number)
  to_add.each{ |feature_flag| add_feature_flag(feature_flag) }
  to_delete.each{ |feature_flag| remove_feature_flag(feature_flag) }
  set_change_number(new_change_number)
end