<commit_before># Facade that speaks to the content store and rummager. Returns a content
# item for the finder combined with the actual search results from rummager.
class FinderApi
  def initialize(base_path, filter_params)
    @base_path = base_path
    @filter_params = filter_params
  end

  def content_item_with_search_results
    content_item = fetch_content_item
    search_response = fetch_search_response(content_item)
    augment_content_item_with_results(content_item, search_response)
  end

private

  attr_reader :base_path, :filter_params

  def fetch_content_item
    if ENV["DEVELOPMENT_FINDER_JSON"]
      JSON.parse(File.read(ENV["DEVELOPMENT_FINDER_JSON"]))
    else
      Services.content_store.content_item(base_path)
    end
  end

  def fetch_search_response(content_item)
    query = query_builder_class.new(
      finder_content_item: content_item,
      params: filter_params,
    ).call

    Services.rummager.search(query).to_hash
  end

  def augment_content_item_with_results(content_item, search_response)
    content_item = augment_content_item_details_with_results(content_item, search_response)
    augment_facets_with_dynamic_values(content_item, search_response)
    content_item
  end

  def augment_content_item_details_with_results(content_item, search_response)
    content_item['details']['results'] = search_response.fetch("results")
    content_item['details']['total_result_count'] = search_response.fetch("total")

    content_item['details']['pagination'] = build_pagination(
      content_item['details']['default_documents_per_page'],
      search_response.fetch('start'),
      search_response.fetch('total')
    )

    content_item
  end

  def augment_facets_with_dynamic_values(content_item, search_response)
    search_response.fetch("facets", {}).each do |facet_key, facet_details|
      facet = content_item['details']['facets'].find { |f| f['key'] == facet_key }
      facet['allowed_values'] = allowed_values_for_facet_details(facet_details) if facet
    end
  end

  def allowed_values_for_facet_details(facet_details)
    values = facet_details.fetch("options", {})
      .reject { |f| f.dig("value", "title").nil? }
      .map { |f| f.fetch("value", {}) }

    values.map { |value|
      {
        'label' => value.fetch("title", ""),
        'value' => value.fetch("slug", ""),
      }
    }
  end

  def build_pagination(documents_per_page, start_offset, total_results)
    if documents_per_page
      {
        'current_page' => (start_offset / documents_per_page) + 1,
        'total_pages' => (total_results / documents_per_page.to_f).ceil,
      }
    end
  end

  def query_builder_class
    SearchQueryBuilder
  end
end
<commit_msg>Add a content_item method to FinderApi<commit_after># Facade that speaks to the content store and rummager. Returns a content
# item for the finder combined with the actual search results from rummager.
class FinderApi
  def initialize(base_path, filter_params)
    @base_path = base_path
    @filter_params = filter_params
  end

  def content_item
    @content_item ||= fetch_content_item
  end

  def content_item_with_search_results
    search_response = fetch_search_response(content_item)
    augment_content_item_with_results(content_item, search_response)
  end

private

  attr_reader :base_path, :filter_params

  def fetch_content_item
    if ENV["DEVELOPMENT_FINDER_JSON"]
      JSON.parse(File.read(ENV["DEVELOPMENT_FINDER_JSON"]))
    else
      Services.content_store.content_item(base_path)
    end
  end

  def fetch_search_response(content_item)
    query = query_builder_class.new(
      finder_content_item: content_item,
      params: filter_params,
    ).call

    Services.rummager.search(query).to_hash
  end

  def augment_content_item_with_results(content_item, search_response)
    content_item = augment_content_item_details_with_results(content_item, search_response)
    augment_facets_with_dynamic_values(content_item, search_response)
    content_item
  end

  def augment_content_item_details_with_results(content_item, search_response)
    content_item['details']['results'] = search_response.fetch("results")
    content_item['details']['total_result_count'] = search_response.fetch("total")

    content_item['details']['pagination'] = build_pagination(
      content_item['details']['default_documents_per_page'],
      search_response.fetch('start'),
      search_response.fetch('total')
    )

    content_item
  end

  def augment_facets_with_dynamic_values(content_item, search_response)
    search_response.fetch("facets", {}).each do |facet_key, facet_details|
      facet = content_item['details']['facets'].find { |f| f['key'] == facet_key }
      facet['allowed_values'] = allowed_values_for_facet_details(facet_details) if facet
    end
  end

  def allowed_values_for_facet_details(facet_details)
    values = facet_details.fetch("options", {})
      .reject { |f| f.dig("value", "title").nil? }
      .map { |f| f.fetch("value", {}) }

    values.map { |value|
      {
        'label' => value.fetch("title", ""),
        'value' => value.fetch("slug", ""),
      }
    }
  end

  def build_pagination(documents_per_page, start_offset, total_results)
    if documents_per_page
      {
        'current_page' => (start_offset / documents_per_page) + 1,
        'total_pages' => (total_results / documents_per_page.to_f).ceil,
      }
    end
  end

  def query_builder_class
    SearchQueryBuilder
  end
end

{'fraction_non_alphanumeric': 0.09912055698057896, 'fraction_numerical': 0.00036643459142543056, 'mean_word_length': 4.3310546875, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, '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': '1962044', 'n_tokens_mistral': 1756, 'n_tokens_neox': 1714, 'n_words': 306}