% 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_eval).

-export([
    acquire_map_context/6,
    release_map_context/1,
    map_docs/2,
    with_context/2,
    try_compile/4,
    validate_doc_update/5,
    filter_view/3,
    filter_docs/5
]).

-include_lib("couch/include/couch_db.hrl").

-type db_name() :: binary().
-type doc_id() :: binary().
-type ddoc_id() :: binary().
-type language() :: binary().
-type sig() :: binary().
-type lib() :: any().
-type map_fun() :: binary().
-type map_funs() :: [map_fun()].
-type result() :: {doc_id(), [[{any(), any()}]]}.
-type api_mod() :: atom().
-type context() :: {api_mod(), any()}.
-type function_type() :: binary() | atom().
-type function_name() :: binary().
-type function_src() :: binary().
-type error(_Error) :: no_return().
-type user_context() :: any().
-type req() :: any().
-type db() :: any().

-type context_opts() :: #{
    db_name := db_name(),
    ddoc_id => ddoc_id(),
    language => language(),
    sig => sig(),
    lib => lib(),
    map_funs => map_funs(),
    api_mod => api_mod()
}.

-type with_context_opts() :: #{
    language := language()
}.

-callback acquire_map_context(context_opts()) -> {ok, any()} | {error, any()}.
-callback release_map_context(context()) -> ok | {error, any()}.
-callback map_docs(context(), [doc()]) -> {ok, [result()]} | {error, any()}.
-callback acquire_context() -> {ok, any()} | {error, any()}.
-callback release_context(context()) -> ok | {error, any()}.
-callback try_compile(context(), function_type(), function_name(), function_src()) -> ok.
-callback validate_doc_update(ddoc(), doc(), doc(), user_context(), sec_obj()) ->
    ok | {error, any()}.
-callback filter_view(ddoc(), function_name(), [doc()]) -> {true, [result()]} | {error, any()}.
-callback filter_docs(req(), db(), ddoc(), function_name(), [doc()]) ->
    {true, [result()]} | {error, any()}.

-spec acquire_map_context(
    db_name(),
    ddoc_id(),
    language(),
    sig(),
    lib(),
    map_funs()
) ->
    {ok, context()}
    | error({invalid_eval_api_mod, Language :: binary()})
    | error({unknown_eval_api_language, Language :: binary()}).
acquire_map_context(DbName, DDocId, Language, Sig, Lib, MapFuns) ->
    ApiMod = get_api_mod(Language),
    CtxOpts = #{
        db_name => DbName,
        ddoc_id => DDocId,
        language => Language,
        sig => Sig,
        lib => Lib,
        map_funs => MapFuns
    },
    case ApiMod:acquire_map_context(CtxOpts) of
        {ok, Ctx} ->
            {ok, {ApiMod, Ctx}};
        {error, Error} ->
            {error, Error}
    end.

-spec release_map_context(context()) -> ok | {error, any()}.
release_map_context(nil) ->
    ok;
release_map_context({ApiMod, Ctx}) ->
    ApiMod:release_map_context(Ctx).

-spec map_docs(context(), [doc()]) -> {ok, result()} | {error, any()}.
map_docs({ApiMod, Ctx}, Docs) ->
    ApiMod:map_docs(Ctx, Docs).

-spec with_context(with_context_opts(), function()) ->
    any()
    | error({invalid_eval_api_mod, Language :: binary()})
    | error({unknown_eval_api_language, Language :: binary()}).
with_context(#{language := Language}, Fun) ->
    {ok, Ctx} = acquire_context(Language),
    try
        Fun(Ctx)
    after
        release_context(Ctx)
    end.

-spec try_compile(context(), function_type(), function_name(), function_src()) -> ok.
try_compile({_ApiMod, _Ctx}, reduce, <<_/binary>>, disabled) ->
    % Reduce functions may be disabled. Accept that as a valid configuration.
    ok;
try_compile({ApiMod, Ctx}, FuncType, FuncName, FuncSrc) ->
    ApiMod:try_compile(Ctx, FuncType, FuncName, FuncSrc).

validate_doc_update(#doc{body = {Props}} = DDoc, EditDoc, DiskDoc, Ctx, SecObj) ->
    Language = couch_util:get_value(<<"language">>, Props, <<"javascript">>),
    ApiMod = get_api_mod(Language),
    ApiMod:validate_doc_update(DDoc, EditDoc, DiskDoc, Ctx, SecObj).

filter_view(#doc{body = {Props}} = DDoc, VName, Docs) ->
    Language = couch_util:get_value(<<"language">>, Props, <<"javascript">>),
    ApiMod = get_api_mod(Language),
    ApiMod:filter_view(DDoc, VName, Docs).

filter_docs(Req, Db, #doc{body = {Props}} = DDoc, FName, Docs) ->
    Language = couch_util:get_value(<<"language">>, Props, <<"javascript">>),
    ApiMod = get_api_mod(Language),
    ApiMod:filter_docs(Req, Db, DDoc, FName, Docs).

acquire_context(Language) ->
    ApiMod = get_api_mod(Language),
    {ok, Ctx} = ApiMod:acquire_context(),
    {ok, {ApiMod, Ctx}}.

release_context(nil) ->
    ok;
release_context({ApiMod, Ctx}) ->
    ApiMod:release_context(Ctx).

get_api_mod(Language) when is_binary(Language) ->
    try
        LangStr = binary_to_list(Language),
        ModStr =
            case LangStr of
                "javascript" ->
                    config:get("couch_eval.languages", LangStr, "couch_js");
                "query" ->
                    config:get("couch_eval.languages", LangStr, "mango_eval");
                _ ->
                    config:get("couch_eval.languages", LangStr)
            end,
        case ModStr of
            undefined -> erlang:error({unknown_eval_api_language, Language});
            _ -> list_to_existing_atom(ModStr)
        end
    catch
        error:badarg ->
            erlang:error({invalid_eval_api_mod, Language})
    end.
