class FeedsController < ActionController::API
  def show
    connection = ActiveRecord::Base.connection
    account = connection.exec_query(
      "SELECT id, handle, display_name FROM accounts WHERE handle = 'reader-42'",
    ).first
    articles = connection.exec_query(
      "SELECT id, title, published_at::text AS published_at FROM articles " \
      "WHERE author_id = #{Integer(account.fetch('id'))} " \
      "ORDER BY published_at DESC LIMIT 20",
    ).to_a
    ids = articles.map { |article| Integer(article.fetch("id")) }
    feedback = connection.exec_query(
      "SELECT article_id, count(*)::integer AS count FROM feedback " \
      "WHERE article_id = ANY(ARRAY[#{ids.join(',')}]::bigint[]) " \
      "GROUP BY article_id",
    ).to_a
    render json: { account: account, articles: articles, feedback: feedback }
  end

  def naive
    connection = ActiveRecord::Base.connection
    account = connection.exec_query(
      "SELECT id, handle, display_name FROM accounts WHERE handle = 'reader-42'",
    ).first
    articles = connection.exec_query(
      "SELECT id, title, published_at::text AS published_at FROM articles " \
      "WHERE author_id = #{Integer(account.fetch('id'))} " \
      "ORDER BY published_at DESC LIMIT 20",
    ).to_a
    feedback = articles.map do |article|
      connection.exec_query(
        "SELECT article_id, count(*)::integer AS count FROM feedback " \
        "WHERE article_id = #{Integer(article.fetch('id'))} GROUP BY article_id",
      ).first
    end.compact
    render json: { account: account, articles: articles, feedback: feedback }
  end

  def serial
    count = Integer(params.fetch(:count), 10)
    unless (0..64).cover?(count)
      return render json: { error: "count must be between 0 and 64" }, status: :bad_request
    end

    query_ms = 0.0
    connection = ActiveRecord::Base.connection
    count.times do
      started = Process.clock_gettime(Process::CLOCK_MONOTONIC)
      connection.exec_query("SELECT 1")
      query_ms += (Process.clock_gettime(Process::CLOCK_MONOTONIC) - started) * 1000
    end
    render json: { sequential_queries: count, database_ms: query_ms }
  rescue ArgumentError
    render json: { error: "count must be an integer" }, status: :bad_request
  end

  def db_probe
    connection = ActiveRecord::Base.connection
    started = Process.clock_gettime(Process::CLOCK_MONOTONIC)
    connection.exec_query("SELECT 1")
    query_ms = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - started) * 1000
    render json: { database_ms: query_ms }
  end
end
