%%%------------------------------------
%%% module  : mod_server_call
%%% @author  : xyao
%%% email   : jiexiaowen@gmail.com
%%% Created : 2011.12.16
%%% description: 角色call处理
%%%------------------------------------
-module(mod_server_call).
-export([handle_call/3]).
-include("common.hrl").
-include("predefine.hrl").
-include("server.hrl").

%%==========基础功能base============


%%获取用户信息
handle_call('base_data', _from, Status) ->
    {reply, Status, Status};

%% 调用模块函数
handle_call({'apply_call', CallType, Module, Method, Args},  _From, Status) ->
    if
        CallType == ?APPLY_CALL -> NewArgs = Args;
        CallType == ?APPLY_CALL_STATUS orelse
        CallType == ?APPLY_CALL_SAVE -> NewArgs = [Status|Args]
    end,
    case apply(Module, Method, NewArgs) of
        NewStatus when is_record(NewStatus, player_status) ->
            lib_player:log_operation_combat_power(Status, NewStatus, 0, 0, {Module, Method}),
            {reply, true, NewStatus};
        {Reply, NewStatus} when is_record(NewStatus, player_status) ->
            lib_player:log_operation_combat_power(Status, NewStatus, 0, 0, {Module, Method}),
            {reply, Reply, NewStatus};
        {Reply, NewStatus, _} when is_record(NewStatus, player_status) ->
            lib_player:log_operation_combat_power(Status, NewStatus, 0, 0, {Module, Method}),
            {reply, Reply, NewStatus};%道具验证
        {false, Reply, NewStatus} when is_record(NewStatus, player_status) ->
            lib_player:log_operation_combat_power(Status, NewStatus, 0, 0, {Module, Method}),
            {reply, Reply, NewStatus};
        _Info when CallType == ?APPLY_CALL_SAVE ->
            ?ERR("mod_server_call apply_call error CallType = ~p, Moudle = ~p, Method = ~p, Args = ~p, Reason = ~p~n",
                [CallType, Module, Method, Args, _Info]),
            throw(player_status),
            {reply, false, Status};
        Reply ->
            {reply, Reply, Status}
    end;

%% 调用模块函数，更新角色信息。
%% 注意！！需要MFA中自己调用gen_server:reply/2返回
handle_call({fast_call, {Module, Fun, Args}}, From, Status) ->
    %% 提示：由于一些操作直接写入数据库，这里出错时可能执行了部分（可能涉及元宝类）
    %% 所以不建议采用try catch捕捉出错后，以原始Status回写状态数据
    %% 直接让玩家进程崩溃掉线即可，一般情况下MFA内部也是这个原则
    Return = apply(Module, Fun, [Status, From | Args]),
    case Return of
        {ok, NewStatus} when is_record(NewStatus, player_status) ->
            lib_player:log_operation_combat_power(Status, NewStatus, 0, 0, {Module, Fun}),
            {noreply, NewStatus};
        NewStatus when is_record(NewStatus, player_status) ->
            lib_player:log_operation_combat_power(Status, NewStatus, 0, 0, {Module, Fun}),
            {noreply, NewStatus};
        _ when Return =:= ok orelse Return =:= ignore orelse Return =:= skip ->
            {noreply, Status};
        _Other ->
            ?ERR("~p fast_call error MFA = ~p, Reason = ~p~n", [?MODULE, {Module, Fun}, _Other]),
            {noreply, Status}
    end;

%% 按照格式（ResultForm）返回记录中的字段集合
handle_call({'get_form_data', ResultForm}, _From, Status) ->
    Result = util:record_return_form(Status, ResultForm),
    {reply, Result, Status};

%% 默认匹配
handle_call(Event, _From, Status) ->
    catch ?ERR("mod_server:handle_call not match: ~p", [Event]),
    {reply, ok, Status}.
