% 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) ->
    couch_httpd: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, []),
    couch_httpd:etag_respond(Req, CurrentEtag, fun() ->
        JsonReq = couch_httpd_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),
        couch_httpd_external:send_external_response(Req, JsonResp)
    end).


show_etag(#httpd{user_ctx=UserCtx}=Req, Doc, DDoc, More) ->
    Accept = couch_httpd:header_value(Req, "Accept"),
    DocPart = case Doc of
        nil -> nil;
        Doc -> couch_httpd:doc_etag(Doc)
    end,
    couch_httpd:make_etag({couch_httpd: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) ->
    couch_httpd:send_error(Req, 404, <<"update_error">>, <<"Invalid path.">>).

send_doc_update_response(Req, Db, DDoc, UpdateName, Doc, DocId) ->
    JsonReq = couch_httpd_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 couch_httpd: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),
            {[
                {<<"code">>, 201},
                {<<"headers">>, {[
                    {<<"X-Couch-Update-NewRev">>, NewRevStr},
                    {<<"X-Couch-Id">>, NewDoc#doc.id}
                ]}}
                | JsonResp0]};
        [<<"up">>, _Other, {JsonResp0}] ->
            {[{<<"code">>, 200} | JsonResp0]}
    end,
    % todo set location field
    couch_httpd_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);
        _ ->
            couch_httpd:send_error(Req, 404, <<"list_error">>, <<"Bad path.">>)
    end;
handle_view_list_req(#httpd{method='POST'}=Req, Db, DDoc) ->
    {Props} = couch_httpd: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);
        _ ->
            couch_httpd:send_error(Req, 404, <<"list_error">>, <<"Bad path.">>)
    end;
handle_view_list_req(Req, _Db, _DDoc) ->
    couch_httpd: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 = couch_httpd:header_value(Req, "Accept"),
        Parts = {couch_httpd:doc_etag(DDoc), Accept, {Name, Roles}},
        ETag = couch_httpd:make_etag({BaseSig, Parts}),
        case couch_httpd: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, _}, 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,
    couch_httpd:last_chunk(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
    } = couch_httpd_external:parse_external_response(Headers2),
    Headers3 = couch_httpd_external:default_or_content_type(CType, ExtHeaders),
    Acc#lacc{code=Code, headers=Headers3}.

send_list_row(Row, #lacc{qserver = {Proc, _}, 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] ->
        Acc2 = send_non_empty_chunk(fixup_headers(Headers, Acc), Chunk),
        #lacc{resp = Resp2} = Acc2,
        couch_httpd:last_chunk(Resp2),
        {stop, Acc2};
    [<<"end">>, Chunk] ->
        Acc2 = send_non_empty_chunk(Acc, Chunk),
        #lacc{resp = Resp2} = Acc2,
        couch_httpd:last_chunk(Resp2),
        {stop, Acc2}
    catch Error ->
        case Resp of
            undefined ->
                {Code, _, _} = couch_httpd:error_info(Error),
                #lacc{req=Req, headers=Headers} = Acc,
                {ok, Resp2} = couch_httpd:start_chunked_response(Req, Code, Headers),
                Acc2 = Acc#lacc{resp=Resp2, code=Code};
            _ -> Resp2 = Resp, Acc2 = Acc
        end,
        couch_httpd:send_chunked_error(Resp2, Error),
        {stop, Acc2}
    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} = couch_httpd:start_chunked_response(Req, Code, Headers),
    send_non_empty_chunk(Acc#lacc{resp = Resp}, Chunk);
send_non_empty_chunk(#lacc{resp=Resp} = Acc, Chunk) ->
    couch_httpd:send_chunk(Resp, Chunk),
    Acc.


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.
    case couch_util:get_value(<<"headers">>, ExternalResponse, nil) of
    nil ->
        % no JSON headers
        % add our Etag and Vary headers to the response
        {[{<<"headers">>, {[{<<"Etag">>, CurrentEtag}, {<<"Vary">>, <<"Accept">>}]}} | ExternalResponse]};
    JsonHeaders ->
        {[case Field of
        {<<"headers">>, JsonHeaders} -> % add our headers
            JsonHeadersEtagged = json_apply_field({<<"Etag">>, CurrentEtag}, JsonHeaders),
            JsonHeadersVaried = json_apply_field({<<"Vary">>, <<"Accept">>}, JsonHeadersEtagged),
            {<<"headers">>, JsonHeadersVaried};
        _ -> % skip non-header fields
            Field
        end || Field <- ExternalResponse]}
    end.


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