%% Author: mark
%% Created: Sep 15, 2009
%% Description: TODO: Add description to freeswitch_callback
-module(freeswitch_callback).

-behaviour(gen_server).

-record(st, {fsnode, pbxpid}).

-export([start/3, terminate/2, code_change/3, init/1,
	 handle_call/3, handle_cast/2, handle_info/2, fetch_handler/1]).

start(Node, Section, Pid) ->
    gen_server:start(?MODULE, [Node, Section, Pid], []).

init([Node, Section, Pid]) ->
	io:format( "freeswitch_callback:init( [Node=~w, Section=~w, Pid=~w])~n", [Node, Section, Pid] ),
    {ok, #st{fsnode=Node, pbxpid=Pid}}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

%%
%% Callback for freeswitch:start_fetch_handler() called in freeswitch_bind:init()
%%
fetch_handler( FreeswitchNode ) ->
	receive
		{ nodedown, Node } ->
			io:format( "freeswitch_callback:fetch_handler() Node ~w is down~n", [Node] ),
			ok;
		{ fetch, Section, Tag, Key, Value, FetchId, Params } ->
			io:format( "freeswitch_callback:fetch_handler() Invoking xml_fetch()~n" ),
		    {ok, Xml} = xml_fetch( {fetch, Section, Tag, Key, Value, Params} ),
			io:format( "freeswitch_callback:fetch_handler() Sending reply to FreeswitchNode ~w: ~s~n", [FreeswitchNode, Xml] ),
			FreeswitchNode ! { fetch_reply, FetchId, Xml },
			io:format( "freeswitch_callback:fetch_handler() Reply sent~n" ),
			ok
	end,
	{ ok } = fetch_handler( FreeswitchNode ),
	{ ok }.

%%
%%	Configuration handler replies that the requested document section, tag, and key are not
%%	found.
%%
xml_fetch({fetch, configuration, Tag, Key, Value, Params}) ->
	io:format( "freeswitch_callback:handle_call( {fetch, configuration, Tag=~s, Key=~s, Value=~s, Params=~w} )~n",
		[Tag, Key, Value, Params]),
	Xml =
"<document type=\"freeswitch/xml\">
	<section name=\"result\">
		<result status=\"not found\" />
	</section>
</document>",
	{ok, Xml };

%%
%%	Directory handler replies that the requested document section, tag, and key are not
%%	found.
%%
xml_fetch({fetch, directory, Tag, Key, Value, Params}) ->
	io:format( "freeswitch_callback:xml_fetch( {fetch, directory, Tag=~s, Key=~s, Value=~s, Params=~w} )~n",
		[Tag, Key, Value, Params]),
	Xml =
"<document type=\"freeswitch/xml\">
	<section name=\"result\">
		<result status=\"not found\" />
	</section>
</document>",
	{ok, Xml };

%%
%%	Dialplan handler replies that the requested document section, tag, and key are not
%%	found.
%%
xml_fetch({fetch, dialplan, Tag, Key, Value, Params}) ->
	io:format( "freeswitch_callback:xml_fetch( {fetch, dialplan, Tag=~s, Key=~s, Value=~s, Params=~w} )~n",
		[Tag, Key, Value, Params]),
	Xml =
"<document type=\"freeswitch/xml\">
	<section name=\"result\">
		<result status=\"not found\" />
	</section>
</document>",
	{ok, Xml };

%%
%%	Default handler replies that the requested document section, tag, and key are not
%%	found.
%%
xml_fetch({fetch, Section, Tag, Key, Value, Params}) ->
	io:format( "freeswitch_callback:xml_fetch( {fetch, Section=~w, Tag=~s, Key=~s, Value=~s, Params=~w} )~n",
		[Section, Tag, Key, Value, Params]),
	Xml =
"<document type=\"freeswitch/xml\">
	<section name=\"result\">
		<result status=\"not found\" />
	</section>
</document>",
	{ok, Xml };

%%
%%	If the request isn't recognized, just log it.
%%
xml_fetch( Request ) ->
	io:format( "freeswitch_callback:xml_fetch( Request=~w ) not recognized~n",
		[Request]),
	Xml =
"<document type=\"freeswitch/xml\">
	<section name=\"result\">
		<result status=\"not found\" />
	</section>
</document>",
	{ok, Xml }.


%%
%%	If the request isn't recognized, just log it and do nothing.
%%
handle_call(Request, _From, State) ->
    io:format("freeswitch_callback:handle_call( ~w, _From, State) unrecognized request~n",
		[Request]),
    {reply, {error, unrecognized_request}, State}.

handle_cast(Message, State) ->
    error_logger:error_msg("~p received unrecognized cast ~p~n",
			   [self(), Message]),
    {noreply, State}.

handle_info({fetch, Section, Tag, Key, Value, FetchID, Params}, #st{fsnode=Node, pbxpid=Pid}=State) ->
    {ok, XML} = gen_server:call(Pid, {fetch, Section, Tag, Key, Value, Params}),
    {api, Node} ! {fetch_reply, FetchID, XML},
    receive
	ok ->
	    {noreply, State};
	{error, Reason} ->
	    {stop, {error, Reason}, State}
    end.
