%%%-------------------------------------------------------------------
%%% @author aresei
%%% @copyright (C) 2023, <COMPANY>
%%% @doc
%%% @end
%%%-------------------------------------------------------------------
-module(iot_device_sup).
-include("iot.hrl").

-behaviour(supervisor).

-export([start_link/0, init/1, delete_device/1, ensured_device_started/1]).

start_link() ->
    supervisor:start_link({local, ?MODULE}, ?MODULE, []).

init([]) ->
    %% 启动主机相关的devices
    {ok, DeviceInfos} = device_bo:get_all_devices(),
    Specs = lists:map(fun child_spec/1, DeviceInfos),

    {ok, {#{strategy => one_for_one, intensity => 1000, period => 3600}, Specs}}.

-spec ensured_device_started(UUID :: binary()) -> {ok, Pid :: pid()} | {error, Reason :: any()}.
ensured_device_started(DeviceUUID) when is_binary(DeviceUUID) ->
    case iot_device:get_pid(DeviceUUID) of
        undefined ->
            case supervisor:start_child(?MODULE, child_spec(DeviceUUID)) of
                {ok, Pid} when is_pid(Pid) ->
                    {ok, Pid};
                {error, {'already_started', Pid}} when is_pid(Pid) ->
                    {ok, Pid};
                {error, Error} ->
                    {error, Error}
            end;
        Pid when is_pid(Pid) ->
            {ok, Pid}
    end.

delete_device(UUID) when is_binary(UUID) ->
    Id = iot_device:get_name(UUID),
    ok = supervisor:terminate_child(?MODULE, Id),
    supervisor:delete_child(?MODULE, Id).

child_spec(DeviceUUID) when is_binary(DeviceUUID) ->
    Name = iot_device:get_name(DeviceUUID),
    #{id => Name,
        start => {iot_device, start_link, [Name, DeviceUUID]},
        restart => permanent,
        shutdown => 2000,
        type => worker,
        modules => ['iot_device']};
child_spec(DeviceInfo = #{<<"device_uuid">> := DeviceUUID}) when is_binary(DeviceUUID) ->
    Name = iot_device:get_name(DeviceUUID),
    #{id => Name,
        start => {iot_device, start_link, [Name, DeviceInfo]},
        restart => permanent,
        shutdown => 2000,
        type => worker,
        modules => ['iot_device']}.