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

-export([
    handle_doc_show_req/3,
    handle_doc_update_req/3,
    handle_view_list_req/3,
    list_cb/2
]).

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

% /db/_design/foo/_show/bar/docid
% show converts a json doc to a response of any content-type.
% it looks up the doc an then passes it to the query server.
% then it sends the response from the query server to the http client.

maybe_open_doc(Db, DocId) ->
    case catch couch_httpd_db:couch_doc_open(Db, DocId, nil, [conflicts]) of
        #doc{} = Doc -> Doc;
        {not_found, _} -> nil
    end.

handle_doc_show_req(#httpd{
        path_parts=[_, _, _, _, ShowName, DocId]
    }=Req, Db, DDoc) ->

    % open the doc
    Doc = maybe_open_doc(Db, DocId),

    % we don't handle revs here b/c they are an internal api
    % returns 404 if there is no doc with DocId
    handle_doc_show(Req, Db, DDoc, ShowName, Doc, DocId);

handle_doc_show_req(#httpd{
        path_parts=[_, _, _, _, ShowName, DocId|Rest]
    }=Req, Db, DDoc) ->

    DocParts = [DocId|Rest],
    DocId1 = ?l2b(string:join([?b2l(P)|| P <- DocParts], "/")),

    % open the doc
    Doc = maybe_open_doc(Db, DocId1),

    % we don't handle revs here b/c they are an internal api
    % pass 404 docs to the show function
    handle_doc_show(Req, Db, DDoc, ShowName, Doc, DocId1);

handle_doc_show_req(#httpd{
        path_parts=[_, _, _, _, ShowName]
    }=Req, Db, DDoc) ->
    % with no docid the doc is nil
    handle_doc_show(Req, Db, DDoc, ShowName, nil);

handle_doc_show_req(Req, _Db, _DDoc) ->
    chttpd:send_error(Req, 404, <<"show_error">>, <<"Invalid path.">>).

handle_doc_show(Req, Db, DDoc, ShowName, Doc) ->
    handle_doc_show(Req, Db, DDoc, ShowName, Doc, null).

handle_doc_show(Req, Db, DDoc, ShowName, Doc, DocId) ->
    % get responder for ddoc/showname
    CurrentEtag = show_etag(Req, Doc, DDoc, []),
    chttpd:etag_respond(Req, CurrentEtag, fun() ->
        JsonReq = chttpd_external:json_req_obj(Req, Db, DocId),
        JsonDoc = couch_query_servers:json_doc(Doc),
        [<<"resp">>, ExternalResp] =
            couch_query_servers:ddoc_prompt(DDoc, [<<"shows">>, ShowName],
                [JsonDoc, JsonReq]),
        JsonResp = apply_etag(ExternalResp, CurrentEtag),
        chttpd_external:send_external_response(Req, JsonResp)
    end).


show_etag(#httpd{user_ctx=UserCtx}=Req, Doc, DDoc, More) ->
    Accept = chttpd:header_value(Req, "Accept"),
    DocPart = case Doc of
        nil -> nil;
        Doc -> chttpd:doc_etag(Doc)
    end,
    chttpd:make_etag({chttpd:doc_etag(DDoc), DocPart, Accept,
        {UserCtx#user_ctx.name, UserCtx#user_ctx.roles}, More}).

% updates a doc based on a request
% handle_doc_update_req(#httpd{method = 'GET'}=Req, _Db, _DDoc) ->
%     % anything but GET
%     send_method_not_allowed(Req, "POST,PUT,DELETE,ETC");

% This call is creating a new doc using an _update function to
% modify the provided request body.
% /db/_design/foo/_update/bar
handle_doc_update_req(#httpd{
        path_parts=[_, _, _, _, UpdateName]
    }=Req, Db, DDoc) ->
    send_doc_update_response(Req, Db, DDoc, UpdateName, nil, null);

% /db/_design/foo/_update/bar/docid
handle_doc_update_req(#httpd{
        path_parts=[_, _, _, _, UpdateName | DocIdParts]
    }=Req, Db, DDoc) ->
    DocId = ?l2b(string:join([?b2l(P) || P <- DocIdParts], "/")),
    Doc = maybe_open_doc(Db, DocId),
    send_doc_update_response(Req, Db, DDoc, UpdateName, Doc, DocId);


handle_doc_update_req(Req, _Db, _DDoc) ->
    chttpd:send_error(Req, 404, <<"update_error">>, <<"Invalid path.">>).

send_doc_update_response(Req, Db, DDoc, UpdateName, Doc, DocId) ->
    JsonReq = chttpd_external:json_req_obj(Req, Db, DocId),
    JsonDoc = couch_query_servers:json_doc(Doc),
    Cmd = [<<"updates">>, UpdateName],
    UpdateResp = couch_query_servers:ddoc_prompt(DDoc, Cmd, [JsonDoc, JsonReq]),
    JsonResp = case UpdateResp of
        [<<"up">>, {NewJsonDoc}, {JsonResp0}] ->
            case chttpd:header_value(
                    Req, "X-Couch-Full-Commit", "false") of
                "true" ->
                    Options = [full_commit, {user_ctx, Req#httpd.user_ctx}];
                _ ->
                    Options = [{user_ctx, Req#httpd.user_ctx}]
            end,
            NewDoc = couch_doc:from_json_obj({NewJsonDoc}),
            couch_doc:validate_docid(NewDoc#doc.id),
            {ok, NewRev} = couch_db:update_doc(Db, NewDoc, Options),
            NewRevStr = couch_doc:rev_to_str(NewRev),
            {JsonResp1} = apply_headers(JsonResp0, [
                {<<"X-Couch-Update-NewRev">>, NewRevStr},
                {<<"X-Couch-Id">>, NewDoc#doc.id}
            ]),
            {[{<<"code">>, 201} | JsonResp1]};
        [<<"up">>, _Other, {JsonResp0}] ->
            {[{<<"code">>, 200} | JsonResp0]}
    end,
    % todo set location field
    chttpd_external:send_external_response(Req, JsonResp).


handle_view_list_req(#httpd{method=Method}=Req, Db, DDoc)
    when Method =:= 'GET' orelse Method =:= 'OPTIONS' ->
    case Req#httpd.path_parts of
        [_, _, _DName, _, LName, VName] ->
            % Same design doc for view and list
            handle_view_list(Req, Db, DDoc, LName, DDoc, VName, undefined);
        [_, _, _, _, LName, DName, VName] ->
            % Different design docs for view and list
            VDocId = <<"_design/", DName/binary>>,
            {ok, VDDoc} = couch_db:open_doc(Db, VDocId, [ejson_body]),
            handle_view_list(Req, Db, DDoc, LName, VDDoc, VName, undefined);
        _ ->
            chttpd:send_error(Req, 404, <<"list_error">>, <<"Bad path.">>)
    end;
handle_view_list_req(#httpd{method='POST'}=Req, Db, DDoc) ->
    chttpd:validate_ctype(Req, "application/json"),
    {Props} = chttpd:json_body_obj(Req),
    Keys = proplists:get_value(<<"keys">>, Props),
    case Req#httpd.path_parts of
        [_, _, _DName, _, LName, VName] ->
            handle_view_list(Req, Db, DDoc, LName, DDoc, VName, Keys);
        [_, _, _, _, LName, DName, VName] ->
            % Different design docs for view and list
            VDocId = <<"_design/", DName/binary>>,
            {ok, VDDoc} = couch_db:open_doc(Db, VDocId, [ejson_body]),
            handle_view_list(Req, Db, DDoc, LName, VDDoc, VName, Keys);
        _ ->
            chttpd:send_error(Req, 404, <<"list_error">>, <<"Bad path.">>)
    end;
handle_view_list_req(Req, _Db, _DDoc) ->
    chttpd:send_method_not_allowed(Req, "GET,POST,HEAD").


handle_view_list(Req, Db, DDoc, LName, VDDoc, VName, Keys) ->
    Args0 = couch_mrview_http:parse_params(Req, Keys),
    ETagFun = fun(BaseSig, Acc0) ->
        UserCtx = Req#httpd.user_ctx,
        Name = UserCtx#user_ctx.name,
        Roles = UserCtx#user_ctx.roles,
        Accept = chttpd:header_value(Req, "Accept"),
        Parts = {chttpd:doc_etag(DDoc), Accept, {Name, Roles}},
        ETag = chttpd:make_etag({BaseSig, Parts}),
        case chttpd:etag_match(Req, ETag) of
            true -> throw({etag_match, ETag});
            false -> {ok, Acc0#lacc{etag=ETag}}
        end
    end,
    Args = Args0#mrargs{preflight_fun=ETagFun},
    couch_httpd:etag_maybe(Req, fun() ->
        couch_query_servers:with_ddoc_proc(DDoc, fun(QServer) ->
            Acc = #lacc{db=Db, req=Req, qserver=QServer, lname=LName},
            case VName of
              <<"_all_docs">> ->
                couch_mrview:query_all_docs(Db, Args, fun list_cb/2, Acc);
              _ ->
                couch_mrview:query_view(Db, VDDoc, VName, Args, fun list_cb/2, Acc)
            end
        end)
    end).


list_cb({meta, Meta}, #lacc{code=undefined} = Acc) ->
    MetaProps = case couch_util:get_value(total, Meta) of
        undefined -> [];
        Total -> [{total_rows, Total}]
    end ++ case couch_util:get_value(offset, Meta) of
        undefined -> [];
        Offset -> [{offset, Offset}]
    end ++ case couch_util:get_value(update_seq, Meta) of
        undefined -> [];
        UpdateSeq -> [{update_seq, UpdateSeq}]
    end,
    start_list_resp({MetaProps}, Acc);
list_cb({row, Row}, #lacc{code=undefined} = Acc) ->
    {ok, NewAcc} = start_list_resp({[]}, Acc),
    send_list_row(Row, NewAcc);
list_cb({row, Row}, Acc) ->
    send_list_row(Row, Acc);
list_cb(complete, Acc) ->
    #lacc{qserver = {Proc, _}, req = Req, resp = Resp0} = Acc,
    if Resp0 =:= nil ->
        {ok, #lacc{resp = Resp}} = start_list_resp({[]}, Acc);
    true ->
        Resp = Resp0
    end,
    case couch_query_servers:proc_prompt(Proc, [<<"list_end">>]) of
        [<<"end">>, Data, Headers] ->
            Acc2 = fixup_headers(Headers, Acc#lacc{resp=Resp}),
            #lacc{resp = Resp2} = send_non_empty_chunk(Acc2, Data);
        [<<"end">>, Data] ->
            #lacc{resp = Resp2} = send_non_empty_chunk(Acc#lacc{resp=Resp}, Data)
    end,
    last_chunk(Req, Resp2),
    {ok, Resp2}.

start_list_resp(Head, Acc) ->
    #lacc{db=Db, req=Req, qserver=QServer, lname=LName} = Acc,
    JsonReq = json_req_obj(Req, Db),

    [<<"start">>,Chunk,JsonResp] = couch_query_servers:ddoc_proc_prompt(QServer,
        [<<"lists">>, LName], [Head, JsonReq]),
    Acc2 = send_non_empty_chunk(fixup_headers(JsonResp, Acc), Chunk),
    {ok, Acc2}.

fixup_headers(Headers, #lacc{etag=ETag} = Acc) ->
    Headers2 = apply_etag(Headers, ETag),
    #extern_resp_args{
        code = Code,
        ctype = CType,
        headers = ExtHeaders
    } = chttpd_external:parse_external_response(Headers2),
    Headers3 = chttpd_external:default_or_content_type(CType, ExtHeaders),
    Acc#lacc{code=Code, headers=Headers3}.

send_list_row(Row, #lacc{qserver = {Proc, _}, req = Req, resp = Resp} = Acc) ->
    RowObj = case couch_util:get_value(id, Row) of
        undefined -> [];
        Id -> [{id, Id}]
    end ++ case couch_util:get_value(key, Row) of
        undefined -> [];
        Key -> [{key, Key}]
    end ++ case couch_util:get_value(value, Row) of
        undefined -> [];
        Val -> [{value, Val}]
    end ++ case couch_util:get_value(doc, Row) of
        undefined -> [];
        Doc -> [{doc, Doc}]
    end,
    try couch_query_servers:proc_prompt(Proc, [<<"list_row">>, {RowObj}]) of
    [<<"chunks">>, Chunk, Headers] ->
        Acc2 = send_non_empty_chunk(fixup_headers(Headers, Acc), Chunk),
        {ok, Acc2};
    [<<"chunks">>, Chunk] ->
        Acc2 = send_non_empty_chunk(Acc, Chunk),
        {ok, Acc2};
    [<<"end">>, Chunk, Headers] ->
        #lacc{resp = Resp2} = send_non_empty_chunk(fixup_headers(Headers, Acc), Chunk),
        {ok, Resp3} = last_chunk(Req, Resp2),
        {stop, Resp3};
    [<<"end">>, Chunk] ->
        #lacc{resp = Resp2} = send_non_empty_chunk(Acc, Chunk),
        {ok, Resp3} = last_chunk(Req, Resp2),
        {stop, Resp3}
    catch Error ->
        {ok, Resp2} = case Resp of
            undefined ->
                {Code, _, _} = chttpd:error_info(Error),
                #lacc{req=Req, headers=Headers} = Acc,
                chttpd:start_chunked_response(Req, Code, Headers);
            _ ->
                {ok, Resp}
        end,
        {ok, Resp3} = chttpd:send_chunked_error(Resp2, Error),
        {stop, Resp3}
    end.

send_non_empty_chunk(Acc, []) ->
    Acc;
send_non_empty_chunk(#lacc{resp=undefined} = Acc, Chunk) ->
    #lacc{req=Req, code=Code, headers=Headers} = Acc,
    {ok, Resp} = chttpd:start_chunked_response(Req, Code, Headers),
    send_non_empty_chunk(Acc#lacc{resp = Resp}, Chunk);
send_non_empty_chunk(#lacc{resp=Resp} = Acc, Chunk) ->
    chttpd:send_chunk(Resp, Chunk),
    Acc.


apply_etag(JsonResp, undefined) ->
    JsonResp;
apply_etag({ExternalResponse}, CurrentEtag) ->
    % Here we embark on the delicate task of replacing or creating the
    % headers on the JsonResponse object. We need to control the Etag and
    % Vary headers. If the external function controls the Etag, we'd have to
    % run it to check for a match, which sort of defeats the purpose.
    apply_headers(ExternalResponse, [
        {<<"ETag">>, CurrentEtag},
        {<<"Vary">>, <<"Accept">>}
    ]).

apply_headers(JsonResp, []) ->
    JsonResp;
apply_headers(JsonResp, NewHeaders) ->
    case couch_util:get_value(<<"headers">>, JsonResp) of
        undefined ->
            {[{<<"headers">>, {NewHeaders}}| JsonResp]};
        JsonHeaders ->
            Headers = apply_headers1(JsonHeaders, NewHeaders),
            NewKV = {<<"headers">>, Headers},
            {lists:keyreplace(<<"headers">>, 1, JsonResp, NewKV)}
    end.
apply_headers1(JsonHeaders, [{Key, Value} | Rest]) ->
    NewJsonHeaders = json_apply_field({Key, Value}, JsonHeaders),
    apply_headers1(NewJsonHeaders, Rest);
apply_headers1(JsonHeaders, []) ->
    JsonHeaders.


% Maybe this is in the proplists API
% todo move to couch_util
json_apply_field(H, {L}) ->
    json_apply_field(H, L, []).


json_apply_field({Key, NewValue}, [{Key, _OldVal} | Headers], Acc) ->
    % drop matching keys
    json_apply_field({Key, NewValue}, Headers, Acc);
json_apply_field({Key, NewValue}, [{OtherKey, OtherVal} | Headers], Acc) ->
    % something else is next, leave it alone.
    json_apply_field({Key, NewValue}, Headers, [{OtherKey, OtherVal} | Acc]);
json_apply_field({Key, NewValue}, [], Acc) ->
    % end of list, add ours
    {[{Key, NewValue}|Acc]}.


% This loads the db info if we have a fully loaded db record, but we might not
% have the db locally on this node, so then load the info through fabric.
json_req_obj(Req, #db{main_pid=Pid}=Db) when is_pid(Pid) ->
    chttpd_external:json_req_obj(Req, Db);
json_req_obj(Req, Db) ->
    % use a separate process because we're already in a receive loop, and
    % json_req_obj calls fabric:get_db_info()
    spawn_monitor(fun() -> exit(chttpd_external:json_req_obj(Req, Db)) end),
    receive {'DOWN', _, _, _, JsonReq} -> JsonReq end.

last_chunk(Req, undefined) ->
    chttpd:send_response(Req, 200, [], <<"">>);
last_chunk(_Req, Resp) ->
    chttpd:send_chunk(Resp, []).


-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").

apply_headers_test_() ->
    [
        should_apply_headers(),
        should_apply_headers_with_merge(),
        should_apply_headers_with_merge_overwrite()
    ].

should_apply_headers() ->
    ?_test(begin
        JsonResp = [{<<"code">>, 201}],
        Headers  = [{<<"foo">>, <<"bar">>}],
        {Props} = apply_headers(JsonResp, Headers),
        JsonHeaders = couch_util:get_value(<<"headers">>, Props),
        ?assertEqual({Headers}, JsonHeaders)
    end).

should_apply_headers_with_merge() ->
    ?_test(begin
        BaseHeaders = [{<<"bar">>, <<"baz">>}],
        NewHeaders  = [{<<"foo">>, <<"bar">>}],
        JsonResp = [
            {<<"code">>, 201},
            {<<"headers">>, {BaseHeaders}}
        ],
        {Props} = apply_headers(JsonResp, NewHeaders),
        JsonHeaders = couch_util:get_value(<<"headers">>, Props),
        ExpectedHeaders = {NewHeaders ++ BaseHeaders},
        ?assertEqual(ExpectedHeaders, JsonHeaders)
    end).

should_apply_headers_with_merge_overwrite() ->
    ?_test(begin
        BaseHeaders = [{<<"foo">>, <<"bar">>}],
        NewHeaders  = [{<<"foo">>, <<"baz">>}],
        JsonResp = [
            {<<"code">>, 201},
            {<<"headers">>, {BaseHeaders}}
        ],
        {Props} = apply_headers(JsonResp, NewHeaders),
        JsonHeaders = couch_util:get_value(<<"headers">>, Props),
        ?assertEqual({NewHeaders}, JsonHeaders)
    end).

-endif.
