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


-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, couch_db:get_user_ctx(Db)} | 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]}.

