class RubyReport::Report

def add_report(report)

def add_report(report)
  reports << report
end

def build_header

def build_header
  columns.map do |key|
    header_builder.call(key, self)
  end
end

def build_row(row)

def build_row(row)
  current_row = row_resolver.call(row)
  return [] unless current_row
  Array(decorators).each { |decorator| current_row = decorator.new(current_row, scope) }
  Array(formatters).each { |formatter| current_row = formatter.new(current_row, scope) }
  columns.map do |key|
    row_builder.call(current_row, key, self)
  end
end

def collect_row(row)

def collect_row(row)
  result_row = []
  reports.each do |report|
    result_row +=
      if report == self
        report.build_row(row)
      else
        report.collect_row(row)
      end
  end
  result_row
end

def columns(*keys, decorators: ::RubyReport::Decorator, formatters: ::RubyReport::Formatter)

def columns(*keys, decorators: ::RubyReport::Decorator, formatters: ::RubyReport::Formatter)
  @columns_set = Set.new(keys)
  @decorators = decorators
  @formatters = formatters
end

def decorators

def decorators
  self.class.decorators
end

def each_row

def each_row
  return enum_for(:each_row) unless block_given?
  method =
    if data.respond_to?(:find_each)
      :find_each
    else
      :each
    end
  data.public_send(method) do |row|
    yield collect_row(row)
  end
end

def formatters

def formatters
  self.class.formatters
end

def header

def header
  @header ||= reports.flat_map do |report|
    if report == self
      report.build_header
    else
      report.header
    end
  end
end

def initialize(

def initialize(
  data:, scope: nil, columns: nil,
  header_builder: ::RubyReport::Builder::DefaultHeaderBuilder,
  row_builder: ::RubyReport::Builder::DefaultRowBuilder,
  row_resolver: ->(row) { row }
)
  @data = data
  @scope = scope
  @columns =
    if columns.nil?
      self.class.columns_set || raise("Columns not defined")
    else
      Set.new(columns)
    end
  @header_builder = header_builder
  @row_builder = row_builder
  @row_resolver = row_resolver
  @reports = [self]
end

def prepend_report(report)

def prepend_report(report)
  reports.unshift(report)
end

def rows

def rows
  @rows ||= each_row.to_a
end

def to_with(generator, **opts)

def to_with(generator, **opts)
  report = generator.new
  report.add_report(self, **opts)
  report.generate
end