lib/mix/tasks/dripdrop.setup.ex

defmodule Mix.Tasks.Dripdrop.Setup do
  @shortdoc "Generates one Ecto migration that installs the dripdrop schema"

  @moduledoc """
  Generates a wrapper migration in the host app that calls `DripDrop.Migration`.
  """

  use Mix.Task

  alias DripDrop.MixHelpers

  @impl Mix.Task
  def run(args) do
    {opts, _args, _invalid} =
      OptionParser.parse(args, switches: [repo: :string, no_cron: :boolean])

    repo = MixHelpers.resolve_repo(opts[:repo])
    migrations_dir = MixHelpers.migrations_dir(repo)
    File.mkdir_p!(migrations_dir)

    if MixHelpers.setup_migration_exists?(migrations_dir) do
      Mix.raise("A DripDrop setup migration already exists in #{migrations_dir}")
    end

    path =
      migrations_dir
      |> Path.join("#{MixHelpers.timestamp()}_setup_dripdrop.exs")

    File.write!(path, migration_content(repo, Keyword.get(opts, :no_cron, false)))

    Mix.shell().info("""
    Created migration: #{path}

    Run `mix ecto.migrate` after PgFlow's extension, pgmq, setup, and job
    migrations have been generated.
    """)
  end

  defp migration_content(repo, no_cron?) do
    gen_command = "mix dripdrop.setup" <> if(no_cron?, do: " --no-cron", else: "")

    """
    defmodule #{inspect(repo)}.Migrations.SetupDripdrop do
      @moduledoc \"\"\"
      Installs DripDrop's messaging sequence schema.

      Generated by: `#{gen_command}`

      SQL sources are vendored inside DripDrop:
        - priv/dripdrop/sql/versions/v01/v01_up.sql

      `DripDrop.Migration.up/0` runs via EctoEvolver, tracks the installed
      version through `dripdrop.dripdrop_version`, and is idempotent when the
      latest version is already present.

      Prerequisites (applied as earlier migrations):
        1. Postgres extensions — `mix pgflow.gen.postgres_extensions_migration`
        2. pgmq schema + functions — `mix pgflow.gen.pgmq_migration`
        3. PgFlow core + helpers — `mix pgflow.setup`
      \"\"\"
      use Ecto.Migration

      def up do
        DripDrop.Migration.up()
      end

      def down do
        DripDrop.Migration.down()
      end
    end
    """
  end
end