% Licensed under the Apache License, Version 2.0 (the "License"); you may not
% use this file except in compliance with the License. You may obtain a copy of
% the License at
%
%   http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
% License for the specific language governing permissions and limitations under
% the License.

-module(couch_event_listener_mfa).
-behavior(couch_event_listener).


-export([
    start_link/4,
    enter_loop/4,
    stop/1
]).

-export([
    init/1,
    terminate/2,
    handle_event/3,
    handle_cast/2,
    handle_info/2
]).


-record(st, {
    mod,
    func,
    state,
    parent
}).


start_link(Mod, Func, State, Options) ->
    Parent = case proplists:get_value(parent, Options) of
        P when is_pid(P) -> P;
        _ -> self()
    end,
    Arg = {Parent, Mod, Func, State},
    couch_event_listener:start_link(?MODULE, Arg, Options).


enter_loop(Mod, Func, State, Options) ->
    Parent = case proplists:get_value(parent, Options) of
        P when is_pid(P) ->
            erlang:monitor(process, P),
            P;
        _ ->
            undefined
    end,
    St = #st{
        mod = Mod,
        func = Func,
        state = State,
        parent = Parent
    },
    couch_event_listener:enter_loop(?MODULE, St, Options).


stop(Pid) ->
    couch_event_listener:cast(Pid, shutdown).


init({Parent, Mod, Func, State}) ->
    erlang:monitor(process, Parent),
    {ok, #st{
        mod = Mod,
        func = Func,
        state = State,
        parent = Parent
    }}.


terminate(_Reason, _MFA) ->
    ok.


handle_event(DbName, Event, #st{mod=Mod, func=Func, state=State}=St) ->
    case (catch Mod:Func(DbName, Event, State)) of
        {ok, NewState} ->
            {ok, St#st{state=NewState}};
        stop ->
            {stop, normal, St};
        Else ->
            erlang:error(Else)
    end.


handle_cast(shutdown, St) ->
    {stop, normal, St};

handle_cast(_Msg, St) ->
    {ok, St}.


handle_info({'DOWN', _Ref, process, Parent, _Reason}, #st{parent=Parent}=St) ->
    {stop, normal, St};

handle_info(_Msg, St) ->
    {ok, St}.

