1%% Copyright (c) 2012, Magnus Klaar <klaar@ninenines.eu>
2%%
3%% Permission to use, copy, modify, and/or distribute this software for any
4%% purpose with or without fee is hereby granted, provided that the above
5%% copyright notice and this permission notice appear in all copies.
6%%
7%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15%% @doc Runtime context for events.
16-module(gr_context).
17
18-export([
19    make/1
20]).
21
22make(Options) ->
23    make_(undefined, undefined, undefined, undefined, Options).
24
25make_(_Node, App, Pid, Time, [{'$n', Node}|T]) ->
26    make_(Node, App, Pid, Time, T);
27make_(Node, _App, Pid, Time, [{'$a', App}|T]) ->
28    make_(Node, App, Pid, Time, T);
29make_(Node, App, _Pid, Time, [{'$p', Pid}|T]) ->
30    make_(Node, App, Pid, Time, T);
31make_(Node, App, Pid, _Time, [{'$t', Time}|T]) ->
32    make_(Node, App, Pid, Time, T);
33make_(Node, App, Pid, Time, []) ->
34    Pid2 = case Pid of undefined -> self(); _ -> Pid end,
35    Node2 = case Node of undefined -> node(Pid2); _ -> Node end,
36    App2 = case App of undefined -> application(Pid2); _ -> App end,
37    Time2 = case Time of undefined -> os:timestamp(); _ -> Time end,
38    {Node2, App2, Pid2, Time2}.
39
40application(Pid) when Pid =:= self() ->
41    case application:get_application(group_leader()) of
42        {ok, App} -> App;
43        undefined -> undefined
44    end;
45application(Pid) ->
46    {_, GroupLeader} = erlang:process_info(Pid, group_leader),
47    case application:get_application(GroupLeader) of
48        {ok, App} -> App;
49        undefined -> undefined
50    end.
51
52-ifdef(TEST).
53-include_lib("eunit/include/eunit.hrl").
54
55make_defaults_test() ->
56    {Node, App, Pid, Time} = gr_context:make([]),
57    ?assertEqual(Node, node()),
58    ?assertEqual(Pid, self()),
59    ?assert(is_atom(App)),
60    ?assertMatch({_,_,_}, Time).
61
62
63make_override_test() ->
64    Pid = spawn(fun() -> ok end),
65    {Node, App, Pid, Time} = gr_context:make([
66        {'$n', nodename}, {'$a', appname}, {'$p', Pid}, {'$t', timeval}]),
67    ?assertEqual(nodename, Node),
68    ?assertEqual(appname, App),
69    ?assertEqual(timeval, Time).
70
71-endif.
72