class FilterTable::Factory

def add(method_name, opts = {}, &block)

def add(method_name, opts = {}, &block)
  if method_name.nil?
    throw RuntimeError, "Called filter.add for resource #{@resource} with method name nil!"
  end
  @connectors[method_name.to_sym] =
    Connector.new(opts[:field] || method_name, block, opts)
  self
end

def add_accessor(method_name)

def add_accessor(method_name)
  if method_name.nil?
    throw RuntimeError, "Called filter.add_delegator for resource #{@resource} with method name nil!"
  end
  @accessors.push(method_name)
  self
end

def connect(resource, table_accessor)

def connect(resource, table_accessor)
  # create the table structure
  connectors = @connectors
  struct_fields = connectors.values.map(&:field_name)
  connector_blocks = connectors.map do |method, c|
    [method.to_sym, create_connector(c)]
  end
  # the struct to hold single items from the #entries method
  entry_struct = Struct.new(*struct_fields.map(&:to_sym)) do
    attr_accessor :__filter
    def to_s # rubocop:disable Lint/NestedMethodDefinition
      @__filter || super
    end
  end unless struct_fields.empty?
  # the main filter table
  table = Class.new(Table) {
    connector_blocks.each do |x|
      define_method x[0], &x[1]
    end
    define_method :new_entry do |hashmap, filter = ''|
      return entry_struct.new if hashmap.nil?
      res = entry_struct.new(*struct_fields.map { |x| hashmap[x] })
      res.__filter = filter
      res
    end
  }
  # define all access methods with the parent resource
  accessors = @accessors + @connectors.keys
  accessors.each do |method_name|
    resource.send(:define_method, method_name.to_sym) do |*args, &block|
      filter = table.new(self, method(table_accessor).call, ' with')
      filter.method(method_name.to_sym).call(*args, &block)
    end
  end
end

def create_connector(c)

def create_connector(c)
  return ->(cond = Show) { c.block.call(self, cond) } if !c.block.nil?
  lambda { |condition = Show, &cond_block|
    if condition == Show && !block_given?
      r = where(nil).get_field(c.field_name)
      r = r.flatten.uniq.compact if c.opts[:style] == :simple
      r
    else
      where({ c.field_name => condition }, &cond_block)
    end
  }
end

def initialize

def initialize
  @accessors = []
  @connectors = {}
end

def to_s # rubocop:disable Lint/NestedMethodDefinition

rubocop:disable Lint/NestedMethodDefinition
def to_s # rubocop:disable Lint/NestedMethodDefinition
  @__filter || super
end