defmodule WhoNeedHelp.Application do
  # See https://elixir.hexdocs.pm/Application.html
  # for more information on OTP Applications
  @moduledoc false

  use Application

  @e2e_routes Application.compile_env(:who_need_help, :e2e_routes, false)

  @impl true
  def start(_type, _args) do
    if @e2e_routes do
      boot_id = :crypto.strong_rand_bytes(16) |> Base.url_encode64(padding: false)
      :persistent_term.put({WhoNeedHelp, :e2e_boot_id}, boot_id)
    end

    common_children = [
      WhoNeedHelpWeb.Telemetry,
      WhoNeedHelp.Repo,
      {DNSCluster, query: Application.get_env(:who_need_help, :dns_cluster_query) || :ignore},
      {Phoenix.PubSub, name: WhoNeedHelp.PubSub}
    ]

    oban_config = Application.fetch_env!(:who_need_help, Oban)
    oban_client_config = Keyword.merge(oban_config, queues: [], plugins: [], peer: false)

    role_children =
      case Application.fetch_env!(:who_need_help, :app_role) do
        :web ->
          [
            {Oban, oban_client_config},
            WhoNeedHelpWeb.Presence,
            WhoNeedHelp.TrackingPresenceCleanup,
            WhoNeedHelpWeb.Endpoint
          ]

        :worker ->
          [{Oban, oban_config}, WhoNeedHelpWeb.WorkerMetricsPlug]

        :combined ->
          [
            {Oban, oban_config},
            WhoNeedHelpWeb.Presence,
            WhoNeedHelp.TrackingPresenceCleanup,
            WhoNeedHelpWeb.Endpoint
          ]

        :migrate ->
          [{Oban, oban_client_config}]
      end

    children = common_children ++ role_children

    # See https://elixir.hexdocs.pm/Supervisor.html
    # for other strategies and supported options
    opts = [strategy: :one_for_one, name: WhoNeedHelp.Supervisor]
    Supervisor.start_link(children, opts)
  end

  # Tell Phoenix to update the endpoint configuration
  # whenever the application is updated.
  @impl true
  def config_change(changed, _new, removed) do
    if Application.get_env(:who_need_help, :app_role) in [:web, :combined] do
      WhoNeedHelpWeb.Endpoint.config_change(changed, removed)
    end

    :ok
  end
end
