defmodule Microwaveprop.Repo.Migrations.TuneAutovacuumForHighChurn do
  use Ecto.Migration

  @moduledoc """
  Per-table autovacuum/analyze parameters for the hottest paths.

  Default PG 16 thresholds (`scale_factor 0.2` for vacuum, `0.1` for
  analyze) are too lazy for a handful of tables we hit frequently:

    * `contacts` — every enrichment tick UPDATEs one or more status
      columns. 81 k rows × 0.1 analyze scale = 8 k dead tuples before
      stats refresh; BackfillEnqueueWorker's status-priority ORDER BY
      then picks a bad plan. Drop to 0.02 / 0.01.

    * `grid_tasks` / `hrrr_fetch_tasks` — small queue tables with a
      claim/complete cycle that rewrites every row each hour. Defaults
      mostly keep up, but the claim query's `FOR UPDATE SKIP LOCKED`
      scan benefits from fresh stats. Set thresholds so vacuum/analyze
      fire at 50 modified rows instead of ~(default 50) + 20%.

    * `contact_common_volume_radar` — MechanismClassifyWorker UPDATEs
      bring the analyze stale-tuple counter to ~200 k without ever
      flipping the default 10 % threshold. Matches the contacts
      shape at 0.02 / 0.01.

  All other tables keep PG defaults — including `hrrr_profiles`
  partitions (append-heavy, analyze-fires-naturally on insert) and
  the Oban-owned tables (`oban_jobs`, `oban_producers`, `oban_peers`),
  which Oban's own Pruner handles.

  Reversible — `down` resets each back to the cluster-wide default.
  """

  @high_churn [
    {"contacts", 0.02, 0.01},
    {"grid_tasks", 0.05, 0.02},
    {"hrrr_fetch_tasks", 0.05, 0.02},
    {"contact_common_volume_radar", 0.02, 0.01}
  ]

  def up do
    for {table, vac_scale, analyze_scale} <- @high_churn do
      execute("""
      ALTER TABLE #{table} SET (
        autovacuum_vacuum_scale_factor = #{vac_scale},
        autovacuum_analyze_scale_factor = #{analyze_scale},
        autovacuum_vacuum_threshold = 50,
        autovacuum_analyze_threshold = 50
      )
      """)
    end
  end

  def down do
    for {table, _, _} <- @high_churn do
      execute("""
      ALTER TABLE #{table} RESET (
        autovacuum_vacuum_scale_factor,
        autovacuum_analyze_scale_factor,
        autovacuum_vacuum_threshold,
        autovacuum_analyze_threshold
      )
      """)
    end
  end
end
