defmodule Forum.PublicSiteSupervisor do
  @moduledoc """
  Starts one public-site process for each network with a separate port.
  """
  use DynamicSupervisor

  def start_link(opts) do
    DynamicSupervisor.start_link(__MODULE__, opts, name: __MODULE__)
  end

  @impl true
  def init(_opts) do
    DynamicSupervisor.init(strategy: :one_for_one)
  end

  def get_or_start(network) when is_binary(network) do
    key = Forum.PublicSite.normalize_network(network)

    case Registry.lookup(Forum.ProcessRegistry, {:public_site, key}) do
      [{pid, _}] ->
        {:ok, pid}

      [] ->
        spec = {Forum.PublicSite, network: key}

        case DynamicSupervisor.start_child(__MODULE__, spec) do
          {:ok, pid} -> {:ok, pid}
          {:error, {:already_started, pid}} -> {:ok, pid}
          other -> other
        end
    end
  end

  def public_sites do
    Forum.ProcessRegistry
    |> Registry.select([
      {{{:public_site, :"$1"}, :"$2", :_}, [], [{{:"$1", :"$2"}}]}
    ])
  end

  def start_networks do
    for slug <- Forum.Networks.network_slugs() do
      get_or_start(slug)
    end

    :ok
  end
end
