% 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(mango_util).


-export([
    open_doc/2,
    open_ddocs/1,
    load_ddoc/2,

    defer/3,
    do_defer/3,

    assert_ejson/1,

    to_lower/1,

    enc_dbname/1,
    dec_dbname/1,

    enc_hex/1,
    dec_hex/1,

    lucene_escape_field/1,
    lucene_escape_query_value/1,

    has_suffix/2,

    join/2
]).


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


open_doc(Db, DocId) ->
    Opts = [deleted],
    case mango_util:defer(fabric, open_doc, [Db, DocId, Opts]) of
        {ok, Doc} ->
            {ok, Doc};
        {not_found, _} ->
            not_found;
        _ ->
            ?MANGO_ERROR({error_loading_doc, DocId})
    end.


open_ddocs(Db) ->
    case mango_util:defer(fabric, design_docs, [Db]) of
        {ok, Docs} ->
            {ok, Docs};
        _ ->
            ?MANGO_ERROR(error_loading_ddocs)
    end.


load_ddoc(Db, DDocId) ->
    case mango_util:open_doc(Db, DDocId) of
        {ok, Doc} ->
            {ok, check_lang(Doc)};
        not_found ->
            Body = {[
                {<<"language">>, <<"query">>}
            ]},
            {ok, #doc{id = DDocId, body = Body}}
    end.


defer(Mod, Fun, Args) ->
    %twig:log(error, "MFA: ~p", [{Mod, Fun, Args}]),
    {Pid, Ref} = erlang:spawn_monitor(?MODULE, do_defer, [Mod, Fun, Args]),
    receive
        {'DOWN', Ref, process, Pid, {mango_defer_ok, Value}} ->
            Value;
        {'DOWN', Ref, process, Pid, {mango_defer_throw, Value}} ->
            erlang:throw(Value);
        {'DOWN', Ref, process, Pid, {mango_defer_error, Value}} ->
            erlang:error(Value);
        {'DOWN', Ref, process, Pid, {mango_defer_exit, Value}} ->
            erlang:exit(Value)
    end.


do_defer(Mod, Fun, Args) ->
    try erlang:apply(Mod, Fun, Args) of
        Resp ->
            erlang:exit({mango_defer_ok, Resp})
    catch
        throw:Error ->
            Stack = erlang:get_stacktrace(),
            twig:log(err, "Defered error: ~w~n    ~p", [{throw, Error}, Stack]),
            erlang:exit({mango_defer_throw, Error});
        error:Error ->
            Stack = erlang:get_stacktrace(),
            twig:log(err, "Defered error: ~w~n    ~p", [{error, Error}, Stack]),
            erlang:exit({mango_defer_error, Error});
        exit:Error ->
            Stack = erlang:get_stacktrace(),
            twig:log(err, "Defered error: ~w~n    ~p", [{exit, Error}, Stack]),
            erlang:exit({mango_defer_exit, Error})
    end.


assert_ejson({Props}) ->
    assert_ejson_obj(Props);
assert_ejson(Vals) when is_list(Vals) ->
    assert_ejson_arr(Vals);
assert_ejson(null) ->
    true;
assert_ejson(true) ->
    true;
assert_ejson(false) ->
    true;
assert_ejson(String) when is_binary(String) ->
    true;
assert_ejson(Number) when is_number(Number) ->
    true;
assert_ejson(_Else) ->
    false.


assert_ejson_obj([]) ->
    true;
assert_ejson_obj([{Key, Val} | Rest]) when is_binary(Key) ->
    case assert_ejson(Val) of
        true ->
            assert_ejson_obj(Rest);
        false ->
            false
    end;
assert_ejson_obj(_Else) ->
    false.


assert_ejson_arr([]) ->
    true;
assert_ejson_arr([Val | Rest]) ->
    case assert_ejson(Val) of
        true ->
            assert_ejson_arr(Rest);
        false ->
            false
    end.


check_lang(#doc{id = Id, deleted = true}) ->
    Body = {[
        {<<"language">>, <<"query">>}
    ]},
    #doc{id = Id, body = Body};
check_lang(#doc{body = {Props}} = Doc) ->
    case lists:keyfind(<<"language">>, 1, Props) of
        {<<"language">>, <<"query">>} ->
            Doc;
        Else ->
            ?MANGO_ERROR({invalid_ddoc_lang, Else})
    end.


to_lower(Key) when is_binary(Key) ->
    KStr = binary_to_list(Key),
    KLower = string:to_lower(KStr),
    list_to_binary(KLower).


enc_dbname(<<>>) ->
    <<>>;
enc_dbname(<<A:8/integer, Rest/binary>>) ->
    Bytes = enc_db_byte(A),
    Tail = enc_dbname(Rest),
    <<Bytes/binary, Tail/binary>>.


enc_db_byte(N) when N >= $a, N =< $z -> <<N>>;
enc_db_byte(N) when N >= $0, N =< $9 -> <<N>>;
enc_db_byte(N) when N == $/; N == $_; N == $- -> <<N>>;
enc_db_byte(N) ->
    H = enc_hex_byte(N div 16),
    L = enc_hex_byte(N rem 16),
    <<$$, H:8/integer, L:8/integer>>.


dec_dbname(<<>>) ->
    <<>>;
dec_dbname(<<$$, _:8/integer>>) ->
    throw(invalid_dbname_encoding);
dec_dbname(<<$$, H:8/integer, L:8/integer, Rest/binary>>) ->
    Byte = (dec_hex_byte(H) bsl 4) bor dec_hex_byte(L),
    Tail = dec_dbname(Rest),
    <<Byte:8/integer, Tail/binary>>;
dec_dbname(<<N:8/integer, Rest/binary>>) ->
    Tail = dec_dbname(Rest),
    <<N:8/integer, Tail/binary>>.


enc_hex(<<>>) ->
    <<>>;
enc_hex(<<V:8/integer, Rest/binary>>) ->
    H = enc_hex_byte(V div 16),
    L = enc_hex_byte(V rem 16),
    Tail = enc_hex(Rest),
    <<H:8/integer, L:8/integer, Tail/binary>>.


enc_hex_byte(N) when N >= 0, N < 10 -> $0 + N;
enc_hex_byte(N) when N >= 10, N < 16 -> $a + (N - 10);
enc_hex_byte(N) -> throw({invalid_hex_value, N}).


dec_hex(<<>>) ->
    <<>>;
dec_hex(<<_:8/integer>>) ->
    throw(invalid_hex_string);
dec_hex(<<H:8/integer, L:8/integer, Rest/binary>>) ->
    Byte = (dec_hex_byte(H) bsl 4) bor dec_hex_byte(L),
    Tail = dec_hex(Rest),
    <<Byte:8/integer, Tail/binary>>.


dec_hex_byte(N) when N >= $0, N =< $9 -> (N - $0);
dec_hex_byte(N) when N >= $a, N =< $f -> (N - $a) + 10;
dec_hex_byte(N) when N >= $A, N =< $F -> (N - $A) + 10;
dec_hex_byte(N) -> throw({invalid_hex_character, N}).



lucene_escape_field(Bin) when is_binary(Bin) ->
    Str = binary_to_list(Bin),
    Enc = lucene_escape_field(Str),
    iolist_to_binary(Enc);
lucene_escape_field([H | T]) when is_number(H), H >= 0, H =< 255 ->
    if
        H >= $a, $z >= H ->
            [H | lucene_escape_field(T)];
        H >= $A, $Z >= H ->
            [H | lucene_escape_field(T)];
        H >= $0, $9 >= H ->
            [H | lucene_escape_field(T)];
        true ->
            Hi = enc_hex_byte(H div 16),
            Lo = enc_hex_byte(H rem 16),
            [$_, Hi, Lo | lucene_escape_field(T)]
        end;
lucene_escape_field([]) ->
    [].


lucene_escape_query_value(IoList) when is_list(IoList) ->
    lucene_escape_query_value(iolist_to_binary(IoList));
lucene_escape_query_value(Bin) when is_binary(Bin) ->
    IoList = lucene_escape_qv(Bin),
    iolist_to_binary(IoList).


% This escapes the special Lucene query characters
% listed below as well as any whitespace.
%
%   + - && || ! ( ) { } [ ] ^ ~ * ? : \ " /
%

lucene_escape_qv(<<>>) -> [];
lucene_escape_qv(<<"&&", Rest/binary>>) ->
    ["\\&&" | lucene_escape_qv(Rest)];
lucene_escape_qv(<<"||", Rest/binary>>) ->
    ["\\||" | lucene_escape_qv(Rest)];
lucene_escape_qv(<<C, Rest/binary>>) ->
    NeedsEscape = "+-(){}[]!^~*?:/\\\" \t\r\n",
    Out = case lists:member(C, NeedsEscape) of
        true -> ["\\", C];
        false -> [C]
    end,
    Out ++ lucene_escape_qv(Rest).


has_suffix(Bin, Suffix) when is_binary(Bin), is_binary(Suffix) ->
    SBin = size(Bin),
    SSuffix = size(Suffix),
    if SBin < SSuffix -> false; true ->
        PSize = SBin - SSuffix,
        case Bin of
            <<_:PSize/binary, Suffix/binary>> ->
                true;
            _ ->
                false
        end
    end.


join(_Sep, [Item]) ->
    [Item];
join(Sep, [Item | Rest]) ->
    [Item, Sep | join(Sep, Rest)].
