%% @copyright 2017 Takeru Ohta <phjgt308@gmail.com>
%%
%% @doc API for operating active spans.
%%
%% Most of the functions and types provided in this module are based on the
%% <a href="https://github.com/opentracing/specification/blob/1.1/specification.md">OpenTracing API</a>.
%%
%% === Examples ===
%%
%% ```
%% %% Registers `tracer'
%% Context = passage_span_context_null,
%% Sampler = passage_sampler_all:new(),
%% Reporter = passage_reporter_process:new(self(), span),
%% ok = passage_tracer_registry:register(tracer, Context, Sampler, Reporter),
%%
%% %% Starts a root span
%% RootSpan = passage:start_span(example_root, [{tracer, tracer}]),
%%
%% %% Starts a child span
%% ChildSpan = passage:start_span(example_child, [{child_of, RootSpan}]),
%%
%% %% Finishes spans
%% passage:finish_span(ChildSpan),
%% passage:finish_span(RootSpan),
%%
%% %% Receives the finished spans
%% receive {span, FinishedChildSpan} -> ok end,
%% receive {span, FinishedRootSpan} -> ok end.
%% '''
-module(passage).

-include("opentracing.hrl").

%%------------------------------------------------------------------------------
%% Exported API
%%------------------------------------------------------------------------------
-export([start_span/1, start_span/2]).
-export([finish_span/1, finish_span/2]).
-export([set_operation_name/2]).
-export([set_tags/2]).
-export([set_baggage_items/2]).
-export([get_baggage_items/1]).
-export([log/2, log/3]).
-export([inject_span/4, extract_span/4]).

-export_type([tracer_id/0]).
-export_type([maybe_span/0]).
-export_type([operation_name/0]).
-export_type([start_span_option/0, start_span_options/0]).
-export_type([finish_span_option/0, finish_span_options/0]).
-export_type([tags/0, tag_name/0, tag_value/0]).
-export_type([refs/0, ref/0, ref_type/0]).
-export_type([baggage_items/0, baggage_item_name/0, baggage_item_value/0]).
-export_type([log_fields/0, log_field_name/0, log_field_value/0]).
-export_type([log_option/0, log_options/0]).

%%------------------------------------------------------------------------------
%% Exported Types
%%------------------------------------------------------------------------------
-type tracer_id() :: atom().
%% Tracer identifier.

-type maybe_span() :: passage_span:span() | undefined.
%% Sampled or unsampled span.
%%
%% `undefined' means the span is unsampled.

-type operation_name() :: atom().
%% Operation name.

-type refs() :: [ref()].
%% Span references.

-type ref() :: {ref_type(), passage_span:span()}.
%% Span reference.
%%
%% Note that the values of tags, references and logs of a reference are set to empty
%% when the associated span is created.
%%
%% See also: <a href="https://github.com/opentracing/specification/blob/1.1/specification.md#references-between-spans">References between Spans (The OpenTracing Semantic Specification)</a>

-type ref_type() :: child_of | follows_from.
%% Span reference type.

-type tags() :: #{tag_name() => tag_value()}.
%% Span tags.
%%
%% See also: <a href="https://github.com/opentracing/specification/blob/1.1/semantic_conventions.md#span-tags-table">Standard span tags (OpenTracing API)</a>

-type tag_name() :: atom().
%% Tag name.

-type tag_value() :: term().
%% Tag value.

-type baggage_items() :: #{baggage_item_name() => baggage_item_value()}.
%% Baggage items.
%%
%% Baggage items are just key/value pairs that cross OS process boundaries.

-type baggage_item_name() :: binary().
%% Baggage item name.

-type baggage_item_value() :: binary().
%% Baggage item value.

-type log_fields() :: #{log_field_name() => log_field_value()}.
%% Span log fields.
%%
%% See also: <a href="https://github.com/opentracing/specification/blob/1.1/semantic_conventions.md#log-fields-table">Standard log fields (OpenTracing API)</a>

-type log_field_name() :: atom().
%% Log field name.

-type log_field_value() :: term().
%% Log field value.

-type start_span_options() :: [start_span_option()].
%% Options for {@link start_span/2}.

-type start_span_option() :: {tracer, tracer_id()}
                           | {tags, tags()}
                           | {ref_type(), maybe_span()}
                           | {time, erlang:timestamp()}.
%% <ul>
%%   <li><b>tracer</b>: The tracer used for tracing the span. If this option is omitted, the span will never be a root span. If the span has any valid references, this option will be ignored.</li>
%%   <li><b>time</b>: Start timestamp of the span. The default value is `erlang:timestamp()'.</li>
%%   <li><b>tags</b>: Tags associated to the span. The default value is `#{}'.</li>
%%   <li><b>child_of|follows_from</b>: Specifies a references related to the span. This option can be presented more than once.</li>
%% </ul>

-type finish_span_options() :: [finish_span_option()].
%% Options for {@link finish_span/2}.

-type finish_span_option() :: {time, erlang:timestamp()}.
%% <ul>
%%   <li><b>time</b>: Finish timestamp of the span. The default value is `erlang:timestamp()'.</li>
%% </ul>

-type log_options() :: [log_option()].
%% Options for {@link log/3}.

-type log_option() :: {time, erlang:timestamp()}
                    | error | {error, boolean()}.
%% <ul>
%%   <li><b>time</b>: Timestamp of the log. The default value is `erlang:timestamp()'.</li>
%%   <li><b>error</b>:
%%     If this option presents, the log will be treated as an error log.
%%     That is the `event' field with the value `error' will be added automatically.
%%     In addition, the tag `#{error => true}' will be set to the calling span.
%%   </li>
%% </ul>

%%------------------------------------------------------------------------------
%% Exported Functions
%%------------------------------------------------------------------------------
%% @equiv start_span(OperationName, [])
-spec start_span(operation_name()) -> maybe_span().
start_span(OperationName) ->
    start_span(OperationName, []).

%% @doc Starts a span.
%%
%% If any of the following conditions is matched,
%% a valid span object (i.e., non `undefined') will be returned.
%%
%% <ul>
%%   <li>1. There are any valid (i.e., non `undefined') span references.</li>
%%   <li>2. The `sampling.priority' tag exists and the value is a positive integer.</li>
%%   <li>3. A `tracer' is specified and its sampler has determined to sample next span.</li>
%% </ul>
%%
%% If the first condition matches,
%% the tracer associated with the first reference will be used for tracing the resulting span.
-spec start_span(operation_name(), start_span_options()) -> maybe_span().
start_span(OperationName, Options) ->
    Result =
        (fun Recur ([],                        Acc) -> Acc;
             Recur ([{tracer, T}       | L], error) -> Recur(L, {ok, T});
             Recur ([{_, undefined}    | L],   Acc) -> Recur(L, Acc);
             Recur ([{child_of, _}     | _],     _) -> ignore;
             Recur ([{follows_from, _} | _],     _) -> ignore;
             Recur ([_                 | L],   Acc) -> Recur(L, Acc)
         end)(Options, error),
    case Result of
        error        -> undefined;
        ignore       -> passage_span:start(OperationName, Options);
        {ok, Tracer} -> passage_span:start_root(Tracer, OperationName, Options)
    end.

%% @equiv finish_span(Span, [])
-spec finish_span(maybe_span()) -> ok.
finish_span(Span) ->
    finish_span(Span, []).

%% @doc Finishes the span.
%%
%% The finished span will be sent an external observer via
%% the reporter associated with the tracer of the span.
%%
%% Note that if you call this function on the same span more than once,
%% duplicate reports will be sent.
-spec finish_span(maybe_span(), finish_span_options()) -> ok.
finish_span(undefined, _)  -> ok;
finish_span(Span, Options) ->
    passage_span:finish(Span, Options).

%% @doc Sets the operation name of `Span' to `Name'.
-spec set_operation_name(maybe_span(), operation_name()) -> maybe_span().
set_operation_name(undefined, _) -> undefined;
set_operation_name(Span, Name)   -> passage_span:set_operation_name(Span, Name).

%% @doc Sets the tags of `Span' to `Tags'.
%%
%% Note that the existing tags which have different keys with `Tags' are preserved.
-spec set_tags(maybe_span(), tags()) -> maybe_span().
set_tags(undefined, _) -> undefined;
set_tags(Span, Tags)   -> passage_span:set_tags(Span, Tags).

%% @doc Sets the baggage items of `Span' to `Items'.
%%
%% Note that the existing items which have different keys with `Items' are preserved.
%%
%% See also: <a href="https://github.com/opentracing/specification/blob/1.1/specification.md#set-a-baggage-item">Set a baggage item (The OpenTracing Semantic Specification)</a>
-spec set_baggage_items(maybe_span(), baggage_items()) -> maybe_span().
set_baggage_items(undefined, _) -> undefined;
set_baggage_items(Span, Items)  -> passage_span:set_baggage_items(Span, Items).

%% @doc Returns the baggage items carried by `Span'.
-spec get_baggage_items(Span :: maybe_span()) -> baggage_items().
get_baggage_items(undefined) -> #{};
get_baggage_items(Span)      -> passage_span:get_baggage_items(Span).

%% @equiv log(Span, Fields, [])
-spec log(maybe_span(), log_fields()) -> maybe_span().
log(Span, Fields) ->
    log(Span, Fields, []).

%% @doc Logs the `Fields' to `Span'.
-spec log(maybe_span(), log_fields(), log_options()) -> maybe_span().
log(undefined, _, _)         -> undefined;
log(Span0, Fields0, Options) ->
    case proplists:get_value(error, Options, false) of
        false -> passage_span:log(Span0, Fields0, Options);
        true  ->
            Fields1 = maps:merge(Fields0, #{?LOG_FIELD_EVENT => error}),
            Span1 = passage_span:log(Span0, Fields1, Options),
            passage_span:set_tags(Span1, #{?TAG_ERROR => true})
    end.

%% @doc Injects `Span' into `Carrier'.
-spec inject_span(Span, Format, InjectFun, Carrier) -> Carrier when
      Span :: maybe_span(),
      Format :: passage_span_context:format(),
      InjectFun :: passage_span_context:inject_fun(),
      Carrier :: passage_span_context:carrier().
inject_span(undefined, _, _, Carrier)         -> Carrier;
inject_span(Span, Format, InjectFun, Carrier) ->
    Context = passage_span:get_context(Span),
    Tracer = passage_span:get_tracer(Span),
    case passage_tracer_registry:get_span_context_module(Tracer) of
        error        -> Carrier;
        {ok, Module} -> Module:inject_span_context(Context, Format, InjectFun, Carrier)
    end.

%% @doc Extracts a span from `Carrier'.
%%
%% If `Carrier' has no span context, this function will return `undefined'.
-spec extract_span(Tracer, Format, IterateFun, Carrier) -> maybe_span() when
      Tracer :: tracer_id(),
      Format :: passage_span_context:format(),
      IterateFun :: passage_span_context:iterate_fun(),
      Carrier :: passage_span_context:carrier().
extract_span(Tracer, Format, IterateFun, Carrier) ->
    case passage_tracer_registry:get_span_context_module(Tracer) of
        error        -> undefined;
        {ok, Module} ->
            case Module:extract_span_context(Format, IterateFun, Carrier) of
                error         -> undefined;
                {ok, Context} -> passage_span:make_extracted_span(Tracer, Context)
            end
    end.
