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

-export([
    before_doc_update/3
]).

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

-spec before_doc_update(#doc{}, Db :: any(), couch_db:update_type()) -> #doc{}.
before_doc_update(#doc{id = <<?DESIGN_DOC_PREFIX, _/binary>>} = Doc, _Db, _UpdateType) ->
    % Skip design docs
    Doc;
before_doc_update(#doc{deleted = true} = Doc, _Db, _UpdateType) ->
    % Skip deleted
    Doc;
before_doc_update(#doc{} = Doc, _Db, ?REPLICATED_CHANGES) ->
    % Skip internal replicator updates
    Doc;
before_doc_update(#doc{} = Doc, _Db, _UpdateType) ->
    Body1 = couch_util:json_encode(Doc#doc.body),
    Body2 = couch_util:json_decode(Body1, [return_maps]),
    validate(Body2),
    Doc.

validate(#{} = Body) ->
    validate_key(<<"by_node">>, Body, ["by_node is mandatory"]),
    validate_key(<<"by_range">>, Body, ["by_range is mandatory"]),
    ByNode = maps:get(<<"by_node">>, Body),
    case is_map(ByNode) of
        true -> ok;
        false -> throw({forbidden, ["by_node not an object"]})
    end,
    ByRange = maps:get(<<"by_range">>, Body),
    case is_map(ByRange) of
        true -> ok;
        false -> throw({forbidden, ["by_range not an object"]})
    end,
    % "by_node": {
    %    "node1@xxx.xxx.xxx.xxx": ["00000000-1fffffff",...]
    % ]}
    maps:map(
        fun(Node, Ranges) ->
            validate_by_node(Node, Ranges, ByRange)
        end,
        ByNode
    ),
    % "by_range": {
    %   "00000000-1fffffff": ["node1@xxx.xxx.xxx.xxx", ...]
    % ]}
    maps:map(
        fun(Range, Nodes) ->
            validate_by_range(Range, Nodes, ByNode)
        end,
        ByRange
    ).

validate_by_node(Node, Ranges, ByRange) ->
    validate_array(Ranges, ["by_node", Ranges, "value not an array"]),
    lists:foreach(
        fun(Range) ->
            validate_key(Range, ByRange, ["by_range for", Range, "missing"]),
            Nodes = maps:get(Range, ByRange),
            validate_member(Node, Nodes, ["by_range for", Range, "missing", Node])
        end,
        Ranges
    ).

validate_by_range(Range, Nodes, ByNode) ->
    validate_array(Nodes, ["by_range", Nodes, "value not an array"]),
    lists:foreach(
        fun(Node) ->
            validate_key(Node, ByNode, ["by_node for", Node, "missing"]),
            Ranges = maps:get(Node, ByNode),
            validate_member(Range, Ranges, ["by_node for", Node, "missing", Range])
        end,
        Nodes
    ).

validate_array(Val, _ErrMsg) when is_list(Val) ->
    ok;
validate_array(_Val, ErrMsg) ->
    throw({forbidden, errmsg(ErrMsg)}).

validate_key(Key, #{} = Map, ErrMsg) ->
    case maps:is_key(Key, Map) of
        true -> ok;
        false -> throw({forbidden, errmsg(ErrMsg)})
    end.

validate_member(Val, Array, ErrMsg) when is_list(Array) ->
    case lists:member(Val, Array) of
        true -> ok;
        false -> throw({forbidden, errmsg(ErrMsg)})
    end;
validate_member(_Val, _Array, ErrMsg) ->
    throw({forbidden, errmsg(ErrMsg)}).

errmsg(ErrMsg) when is_list(ErrMsg) ->
    list_to_binary(lists:join(" ", ErrMsg)).
