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

-export([
    insert/3,
    find/5,
    update/4,
    delete/3,
    explain/3
]).

-export([
    collect_cb/2,
    maybe_add_user_ctx/2
]).


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


insert(Db, #doc{}=Doc, Opts) ->
    insert(Db, [Doc], Opts);
insert(Db, {_}=Doc, Opts) ->
    insert(Db, [Doc], Opts);
insert(Db, Docs, Opts0) when is_list(Docs) ->
    Opts1 = maybe_add_user_ctx(Db, Opts0),
    Opts2 = maybe_int_to_str(w, Opts1),
    case fabric:update_docs(Db, Docs, Opts2) of
        {ok, Results0} ->
            {ok, lists:zipwith(fun result_to_json/2, Docs, Results0)};
        {accepted, Results0} ->
            {ok, lists:zipwith(fun result_to_json/2, Docs, Results0)};
        {aborted, Errors} ->
            {error, lists:map(fun result_to_json/1, Errors)}
    end.


find(Db, Selector, Callback, UserAcc, Opts0) ->
    Opts1 = maybe_add_user_ctx(Db, Opts0),
    Opts2 = maybe_int_to_str(r, Opts1),
    {ok, Cursor} = mango_cursor:create(Db, Selector, Opts2),
    mango_cursor:execute(Cursor, Callback, UserAcc).


update(Db, Selector, Update, Options) ->
    Upsert = proplists:get_value(upsert, Options),
    case collect_docs(Db, Selector, Options) of
        {ok, []} when Upsert ->
            InitDoc = mango_doc:update_as_insert(Update),
            case mango_doc:has_operators(InitDoc) of
                true ->
                    ?MANGO_ERROR(invalid_upsert_with_operators);
                false ->
                    % Probably need to catch and rethrow errors from
                    % this function.
                    Doc = couch_doc:from_json_obj(InitDoc),
                    NewDoc = case Doc#doc.id of
                        <<"">> ->
                            Doc#doc{id=couch_uuids:new(), revs={0, []}};
                        _ ->
                            Doc
                    end,
                    insert(Db, NewDoc, Options)
            end;
        {ok, Docs} ->
            NewDocs = lists:map(fun(Doc) ->
                mango_doc:apply_update(Doc, Update)
            end, Docs),
            insert(Db, NewDocs, Options);
        Else ->
            Else
    end.


delete(Db, Selector, Options) ->
    case collect_docs(Db, Selector, Options) of
        {ok, Docs} ->
            NewDocs = lists:map(fun({Props}) ->
                {[
                    {<<"_id">>, proplists:get_value(<<"_id">>, Props)},
                    {<<"_rev">>, proplists:get_value(<<"_rev">>, Props)},
                    {<<"_deleted">>, true}
                ]}
            end, Docs),
            insert(Db, NewDocs, Options);
        Else ->
            Else
    end.


explain(Db, Selector, Opts0) ->
    Opts1 = maybe_add_user_ctx(Db, Opts0),
    Opts2 = maybe_int_to_str(r, Opts1),
    {ok, Cursor} = mango_cursor:create(Db, Selector, Opts2),
    mango_cursor:explain(Cursor).


maybe_add_user_ctx(Db, Opts) ->
    case lists:keyfind(user_ctx, 1, Opts) of
        {user_ctx, _} ->
            Opts;
        false ->
            [{user_ctx, Db#db.user_ctx} | Opts]
    end.


maybe_int_to_str(_Key, []) ->
    [];
maybe_int_to_str(Key, [{Key, Val} | Rest]) when is_integer(Val) ->
    [{Key, integer_to_list(Val)} | maybe_int_to_str(Key, Rest)];
maybe_int_to_str(Key, [KV | Rest]) ->
    [KV | maybe_int_to_str(Key, Rest)].


result_to_json(#doc{id=Id}, Result) ->
    result_to_json(Id, Result);
result_to_json({Props}, Result) ->
    Id = couch_util:get_value(<<"_id">>, Props),
    result_to_json(Id, Result);
result_to_json(DocId, {ok, NewRev}) ->
    {[
        {id, DocId},
        {rev, couch_doc:rev_to_str(NewRev)}
    ]};
result_to_json(DocId, {accepted, NewRev}) ->
    {[
        {id, DocId},
        {rev, couch_doc:rev_to_str(NewRev)},
        {accepted, true}
    ]};
result_to_json(DocId, Error) ->
    % chttpd:error_info/1 because this is coming from fabric
    % and not internal mango operations.
    {_Code, ErrorStr, Reason} = chttpd:error_info(Error),
    {[
        {id, DocId},
        {error, ErrorStr},
        {reason, Reason}
    ]}.


% This is for errors because for some reason we
% need a different return value for errors? Blargh.
result_to_json({{Id, Rev}, Error}) ->
    {_Code, ErrorStr, Reason} = chttpd:error_info(Error),
    {[
        {id, Id},
        {rev, couch_doc:rev_to_str(Rev)},
        {error, ErrorStr},
        {reason, Reason}
    ]}.


collect_docs(Db, Selector, Options) ->
    Cb = fun ?MODULE:collect_cb/2,
    case find(Db, Selector, Cb, [], Options) of
        {ok, Docs} ->
            {ok, lists:reverse(Docs)};
        Else ->
            Else
    end.


collect_cb({row, Doc}, Acc) ->
    {ok, [Doc | Acc]}.

