defmodule Runbox.Runtime.Stage.StateGenerator do
@moduledoc """
Module generates state of run components running on slave node.
"""
alias Runbox.Runtime.Stage.UnitRegistry
alias Toolbox.Runtime.Stage.Unit
alias Toolbox.Scenario.Template.StageBased, as: Template
require Logger
@doc """
Generates state for component template.
"""
@spec generate_for_component({:template, atom}, String.t()) :: {String.t(), UnitRegistry.t()}
def generate_for_component({:template, template}, run_id) do
id = Atom.to_string(template)
unit_registry =
template
|> Template.instances()
|> Enum.map(fn
{:unit, id, attributes} ->
%{id: id, attributes: attributes}
unknown_unit_def ->
Logger.warn(
"Ignored unknown instance definition of #{template} in run #{run_id} - #{inspect(unknown_unit_def)}"
)
[]
end)
|> List.flatten()
|> Enum.map(fn %{id: id, attributes: attrs} -> Unit.new(id, %{}, attrs) end)
|> create_unit_registry(template)
{id, unit_registry}
end
defp create_unit_registry(units, template) do
unit_routings =
template
|> Template.subscriptions()
|> Enum.map(fn {_, _, unit_routing} -> unit_routing end)
|> List.flatten()
empty_unit_registry = UnitRegistry.new(unit_routings)
Enum.reduce(units, empty_unit_registry, fn unit, unit_registry ->
unit_registry = UnitRegistry.register(unit_registry, unit)
unit_registry
end)
end
end