%%% -------------------------------------------------------
%%% @author < >
%%% @doc
%%% @end
%%% -------------------------------------------------------
-module(clusters_zone_api).
-export([
        zone_type_list/0
        ,get_zone_average_lv/3
        ,get_zone_average_lv/4
        ,get_zone_server_ids/3
        ,get_zone_server_ids/4
        ,get_zone_server_infos/3
        ,get_zone_server_infos/4
        ,get_zone_type_max_id/2
        ,get_module_zone/2
        ,get_module_zone/3
        ,get_zone/2
        ,zone_change/5
        ,remove_same_zone_func/4
        ,sync_zone_func/2
    ]).
-include("common.hrl").
-include("clusters.hrl").
-include("clusters_zone.hrl").
-include("def_module.hrl").
-include("custom_act.hrl").

zone_type_list() ->
    ?ZONE_TYPE_LIST.

%% 获取功能分区平均世界等级
%% DefaultLv :: 默认世界等级，假如分区不存在或者call超时情况下返回默认等级
get_zone_average_lv(ModuleId, ZoneId, DefaultLv) ->
    get_zone_average_lv(ModuleId, 0, ZoneId, DefaultLv).

get_zone_average_lv(ModuleId, SubModuleId, ZoneId, DefaultLv) ->
    ZoneType = data_clusters_zone:get_zone_type(ModuleId, SubModuleId),
    case catch clusters_zone:call_mgr(ZoneType, {get_zone_average_lv, ZoneId, DefaultLv}, 2000) of
       {'EXIT', Reason} -> ?ERR("error:~p~n", [Reason]), DefaultLv;
       WorldLv -> WorldLv
    end.

%% 获取功能分区的服务器id
%% DefaultServerIds :: 默认初始的服务器ids，假如分区不存在或者call超时情况下返回默认
get_zone_server_ids(ModuleId, ZoneId, DefaultServerIds) ->
    get_zone_server_ids(ModuleId, 0, ZoneId, DefaultServerIds).

get_zone_server_ids(ModuleId, SubModuleId, ZoneId, DefaultServerIds) ->
    ZoneType = data_clusters_zone:get_zone_type(ModuleId, SubModuleId),
    case catch clusters_zone:call_mgr(ZoneType, {get_zone_server_ids, ZoneId, DefaultServerIds}, 2000) of
       {'EXIT', Reason} -> ?ERR("error:~p~n", [Reason]), DefaultServerIds;
       ServerIds -> ServerIds
    end.

%% 获取功能分区的服务器信息列表
%% DefaultServerInfos :: 默认初始的服务器信息列表，假如分区不存在或者call超时情况下返回默认
get_zone_server_infos(ModuleId, ZoneId, DefaultServerInfos) ->
    get_zone_server_infos(ModuleId, 0, ZoneId, DefaultServerInfos).

get_zone_server_infos(ModuleId, SubModuleId, ZoneId, DefaultServerInfos) ->
    ZoneType = data_clusters_zone:get_zone_type(ModuleId, SubModuleId),
    case catch clusters_zone:call_mgr(ZoneType, {get_zone_server_infos, ZoneId, DefaultServerInfos}, 2000) of
       {'EXIT', Reason} -> ?ERR("error:~p~n", [Reason]), DefaultServerInfos;
       ServerInfos -> ServerInfos
    end.

%% 获取分区类型的分区最大值id 即分区数量
%% DefaultNum :: 默认初始的分区数量，假如分区不存在或者call超时情况下返回默认
get_zone_type_max_id(ZoneType, DefaultNum) ->
    case catch clusters_zone:call_mgr(ZoneType, {get_zone_type_max_id, DefaultNum}, 2000) of
       {'EXIT', Reason} -> ?ERR("error:~p~n", [Reason]), DefaultNum;
       Num -> Num
    end.

%% 获取服务器功能所在分区
%% @return: integer
get_module_zone(ModuleId, ServerId) ->
    get_module_zone(ModuleId, 0, ServerId).

get_module_zone(ModuleId, SubModuleId, ServerId) ->
    ZoneType = data_clusters_zone:get_zone_type(ModuleId, SubModuleId),
    clusters_zone_api:get_zone(ZoneType, ServerId).

%% 获取服务器所在分区
%% @return: integer
get_zone(ZoneType, ServerId) ->
    Key = {ZoneType, ServerId},
    case catch ets:lookup(?ETS_ZONE_ROUTE, Key) of
        [#zone_route{zone=ZoneId}] -> ZoneId;
        _R ->
            ?ERR("get_zone fail: ~n zone_type=~p, server_id=~p, ~nreason=~n~p~n", [ZoneType, ServerId, _R]),
            0
    end.

%% 游戏服分区划定更改回调接口
zone_change(ZoneType, ChangeServerId, OldZone, NewZone, MainServerId) ->
    ?PRINT("zone change server_id:~w, ~w, ~w->~w, ~w~n", [ChangeServerId, OldZone, NewZone, MainServerId]),
    Key = {ZoneType, ChangeServerId},
    ets:update_element(?ETS_ZONE_ROUTE, Key, {#zone_route.key, NewZone}), %% 更新区域路由信息
    FuncList = [
        %% ModuleId::功能Id, SubModuleId::子功能Id, M::模块名, F::启动函数, A::参数列表}
    ],
    %% 执行与当前分区类型相匹的模块方法列表
    execute_zone_func_list(ZoneType, FuncList),
    ok.

%% 游戏服合服分区不变，清理被合服数据回调接口
remove_same_zone_func(ZoneType, ZoneId, MainSrvId, MergeSrvId) ->
    ?PRINT("zone same delete server_id:~w,~w->~w~n", [ZoneType, ZoneId, [MainSrvId, MergeSrvId]]),
    FuncList = [
        %% {ModuleId::功能Id, SubModuleId::子功能Id, M::模块名, F::启动函数, A::参数列表}
    ],
    %% 执行与当前分区类型相匹的模块方法列表
    execute_zone_func_list(ZoneType, FuncList),
    ok.

%% 分区启动完成，向各游戏服同步数据回调接口
sync_zone_func(ZoneType, ZoneBase) ->
    #zone_base{server_id = ServerId, zone = _ZoneId, merge_ids = _MergeIds} = ZoneBase,
    case clusters_center:find_node(ServerId) of
        undefined -> ?ERR("server node not find:~p~n", [ZoneBase]);
        _Node ->
            FuncList = [
                %% {ModuleId::功能Id, SubModuleId::子功能Id, M::模块名, F::启动函数, A::参数列表}
            ],
            %% 执行与当前分区类型相匹的模块方法列表
            execute_zone_func_list(ZoneType, FuncList)
    end.

%% 执行与当前分区类型相匹的模块方法列表
execute_zone_func_list(ZoneType, FuncList) ->
    F = fun({ModuleId, SubModuleId, M, F, A}) ->
        case data_clusters_zone:get_zone_type(ModuleId, SubModuleId) of
            ZoneType ->
                case catch apply(M, F, A) of
                    {'EXIT', Reason} -> ?ERR("zone_func error:~p,~p,~p~n", [M, F, Reason]);
                    _ -> ok
                end;
            _ -> skip
        end
    end,
    lists:foreach(F, FuncList).
