%%%-------------------------------------------------------------------
%%% @author aresei
%%% @copyright (C) 2023, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 16. 5月 2023 12:48
%%%-------------------------------------------------------------------
-module(host_bo).
-author("aresei").
-include("iot.hrl").

%% API
-export([get_all_hosts/0, change_status/2, get_host_by_uuid/1, get_host_by_id/1]).

-spec get_all_hosts() -> UUIDList :: [binary()].
get_all_hosts() ->
    case mysql_pool:get_all(mysql_iot, <<"SELECT uuid FROM host where uuid != ''">>) of
        {ok, Hosts} ->
            lists:map(fun(#{<<"uuid">> := UUID}) -> UUID end, Hosts);
        {error, _} ->
            []
    end.

-spec get_host_by_uuid(UUID :: binary()) -> undefined | {ok, HostInfo :: map()}.
get_host_by_uuid(UUID) when is_binary(UUID) ->
    mysql_pool:get_row(mysql_iot, <<"SELECT * FROM host WHERE uuid = ? LIMIT 1">>, [UUID]).

-spec get_host_by_id(HostId :: integer()) -> undefined | {ok, HostInfo :: map()}.
get_host_by_id(HostId) when is_integer(HostId) ->
    mysql_pool:get_row(mysql_iot, <<"SELECT * FROM host WHERE id = ? LIMIT 1">>, [HostId]).

%% 修改主机的状态
-spec change_status(UUID :: binary(), Status :: integer()) -> {ok, AffectedRows :: integer()} | {error, Reason :: any()}.
change_status(UUID, NStatus) when is_binary(UUID), is_integer(NStatus) ->
    case change_status0(UUID, NStatus) of
        Result = {ok, _} ->
            event_logs_bo:insert(?EVENT_HOST, UUID, NStatus),
            Result;
        Error ->
            Error
    end.
change_status0(UUID, ?HOST_ONLINE) when is_binary(UUID) ->
    Timestamp = calendar:local_time(),
    case mysql_pool:get_row(mysql_iot, <<"SELECT status FROM host WHERE uuid = ? LIMIT 1">>, [UUID]) of
        %% 第一次更新激活
        {ok, #{<<"status">> := -1}} ->
            mysql_pool:update_by(mysql_iot, <<"UPDATE host SET status = ?, access_at = ?, updated_at = ? WHERE uuid = ? LIMIT 1">>, [?HOST_ONLINE, Timestamp, Timestamp, UUID]);
        {ok, _} ->
            mysql_pool:update_by(mysql_iot, <<"UPDATE host SET status = ?, updated_at = ? WHERE uuid = ? LIMIT 1">>, [?HOST_ONLINE, Timestamp, UUID]);
        undefined ->
            {error, <<"host not found">>}
    end;
change_status0(UUID, ?HOST_OFFLINE) when is_binary(UUID) ->
    mysql_pool:update_by(mysql_iot, <<"UPDATE host SET status = ? WHERE uuid = ? LIMIT 1">>, [?HOST_OFFLINE, UUID]).