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

%% -*- erlang-indent-level: 4;indent-tabs-mode: nil -*-

-module(nouveau_bookmark).

-include_lib("mem3/include/mem3.hrl").

-export([new/0, update/3, unpack/2, pack/1, to_ejson/1]).

new() ->
    #{}.

%% Form a bookmark from the last contribution from each shard range
update(DbName, PreviousBookmark, SearchResults) when is_binary(PreviousBookmark) ->
    update(DbName, unpack(DbName, PreviousBookmark), SearchResults);
update(DbName, {EJson}, SearchResults) when is_list(EJson) ->
    update(DbName, from_ejson({EJson}), SearchResults);
update(DbName, PreviousBookmark, SearchResults) when is_map(PreviousBookmark) ->
    #{<<"hits">> := Hits} = SearchResults,
    NewBookmark0 = lists:foldl(
        fun(#{<<"id">> := Id, <<"order">> := Order}, Acc) ->
            Acc#{range_of(DbName, Id) => Order}
        end,
        new(),
        Hits
    ),
    maps:merge(PreviousBookmark, NewBookmark0).

range_of(DbName, DocId) when is_binary(DbName), is_binary(DocId) ->
    [#shard{range = Range} | _] = mem3_shards:for_docid(DbName, DocId),
    Range;
range_of(DbName, Order) when is_binary(DbName), is_list(Order) ->
    #{<<"@type">> := <<"string">>, <<"value">> := DocId} = lists:last(Order),
    range_of(DbName, DocId).

unpack(_DbName, Empty) when Empty == undefined; Empty == nil; Empty == null ->
    new();
unpack(DbName, PackedBookmark) when is_list(PackedBookmark) ->
    unpack(DbName, list_to_binary(PackedBookmark));
unpack(DbName, PackedBookmark) when is_binary(PackedBookmark) ->
    Bookmark = jiffy:decode(base64:decode(PackedBookmark), [return_maps]),
    maps:from_list([{range_of(DbName, V), V} || V <- Bookmark]).

pack(nil) ->
    null;
pack({EJson}) when is_list(EJson) ->
    pack(from_ejson(EJson));
pack(UnpackedBookmark) when is_map(UnpackedBookmark) ->
    Values = maps:values(UnpackedBookmark),
    Encoded = jiffy:encode(Values),
    Compressed = zlib:compress(Encoded),
    base64:encode(Compressed).

%% legacy use of ejson within mango
from_ejson({Props}) ->
    maps:from_list(Props).

to_ejson(Bookmark) when is_map(Bookmark) ->
    {maps:to_list(Bookmark)}.
