BathHacked/energy-sparks

View on GitHub
app/services/benchmark_content_filter.rb

Summary

Maintainability
A
1 hr
Test Coverage
class BenchmarkContentFilter
  attr_accessor :title
  attr_reader :counts

  def initialize(content)
    @counts = count_content_types(content)
    benchmarks = group_content(content)
    @content = {}

    if benchmarks.count > 0
      extract_title(benchmarks[0])
      filter_content(benchmarks[0])
      extract_rest(benchmarks.drop(1))
    end
  end

  def intro
    @content[:intro] ||= []
  end

  def charts
    @content[:charts] ||= []
  end

  def tables
    @content[:tables] ||= []
  end

  def charts?(count: 1)
    @counts[:chart] && @counts[:chart] >= count
  end

  def tables?(count: 1)
    @counts[:table_composite] && @counts[:table_composite] >= count
  end

  def multi?
    charts?(count: 2) || tables?(count: 2)
  end

private

  def extract_title(content)
    i = content.find_index { |fragment| fragment[:type] == :title && fragment[:content].present?}
    @title = content.delete_at(i)[:content] if i
  end

  def count_content_types(content)
    content.inject({}) do |counts, fragment|
      counts[fragment[:type]] ||= 0
      counts[fragment[:type]] += 1
      counts
    end
  end

  def group_content(content)
    benchmarks = []
    i = -1
    content.each do |fragment|
      if select_fragment?(fragment)
        i += 1 if fragment[:type] == :title
        (benchmarks[i] ||= []) << fragment
      end
    end
    benchmarks
  end

  def filter_content(content)
    key = :intro
    content.each do |fragment|
      if select_fragment?(fragment)
        key = new_key(key, fragment)
        (@content[key] ||= []) << fragment
      end
    end
  end

  def new_key(key, fragment)
    key(fragment) || key
  end

  def key(fragment)
    if fragment[:type] == :chart
      :charts
    elsif fragment[:type] == :table_composite
      :tables
    end
  end

  def select_fragment?(fragment)
    return false unless fragment.present?
    [:title, :chart, :html, :table_composite].include?(fragment[:type]) && fragment[:content].present?
  end

  def extract_rest(benchmarks)
    benchmarks.each do |benchmark|
      parse_benchmark(benchmark)
    end
  end

  def parse_benchmark(benchmark)
    chunk = []
    intro = []
    keep = ''
    benchmark.each do |fragment|
      key = key(fragment)
      keep = key if key

      if keep.blank?
        intro << fragment
      else
        chunk << fragment
      end

      if key
        @content[keep] ||= []
        @content[keep] += intro + chunk
        chunk = []
      end
    end
    if chunk.any? && keep
      @content[keep] ||= []
      @content[keep] += chunk
    end
  end
end