% 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(chttpd_auth_cache).
-behaviour(gen_server).

-export([start_link/0, get_user_creds/2, update_user_creds/3]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
	 code_change/3]).
-export([listen_for_changes/1, changes_callback/2]).

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

-define(CACHE, chttpd_auth_cache_lru).

-record(state, {
    changes_pid,
    last_seq="0"
}).

%% public functions

start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

get_user_creds(Req, UserName) when is_list(UserName) ->
    get_user_creds(Req, ?l2b(UserName));
get_user_creds(_Req, UserName) when is_binary(UserName) ->
    Resp = case couch_auth_cache:get_admin(UserName) of
    nil ->
        get_from_cache(UserName);
    Props ->
        case get_from_cache(UserName) of
        nil ->
            Props;
        UserProps when is_list(UserProps) ->
            couch_auth_cache:add_roles(Props,
	        couch_util:get_value(<<"roles">>, UserProps))
        end
    end,
    maybe_validate_user_creds(Resp).

update_user_creds(_Req, UserDoc, _Ctx) ->
    {_, Ref} = spawn_monitor(fun() ->
        case fabric:update_doc(dbname(), UserDoc, []) of
            {ok, _} ->
                exit(ok);
            Else ->
                exit(Else)
        end
    end),
    receive
        {'DOWN', Ref, _, _, ok} ->
            ok;
        {'DOWN', Ref, _, _, Else} ->
            Else
    end.

get_from_cache(UserName) ->
    try ets_lru:lookup_d(?CACHE, UserName) of
        {ok, Props} ->
            couch_stats:increment_counter([couchdb, auth_cache_hits]),
            couch_log:debug("cache hit for ~s", [UserName]),
            Props;
        _ ->
            couch_stats:increment_counter([couchdb, auth_cache_misses]),
            couch_log:debug("cache miss for ~s", [UserName]),
            case load_user_from_db(UserName) of
                nil ->
                    nil;
                Props ->
                    ets_lru:insert(?CACHE, UserName, Props),
                    Props
            end
    catch
        error:badarg ->
            couch_stats:increment_counter([couchdb, auth_cache_misses]),
            couch_log:debug("cache miss for ~s", [UserName]),
            load_user_from_db(UserName)
    end.

%% gen_server callbacks

init([]) ->
    self() ! {start_listener, 0},
    {ok, #state{}}.

handle_call(_Call, _From, State) ->
    {noreply, State}.

handle_cast(_Msg, State) ->
    {noreply, State}.

handle_info({'DOWN', _, _, Pid, Reason}, #state{changes_pid=Pid} = State) ->
    Seq = case Reason of
        {seq, EndSeq} ->
            EndSeq;
        _ ->
            couch_log:notice("~p changes listener died ~p", [?MODULE, Reason]),
            0
    end,
    erlang:send_after(5000, self(), {start_listener, Seq}),
    {noreply, State#state{last_seq=Seq}};
handle_info({start_listener, Seq}, State) ->
    ensure_auth_ddoc_exists(dbname(), <<"_design/_auth">>),
    {noreply, State#state{changes_pid = spawn_changes(Seq)}};
handle_info(_Msg, State) ->
    {noreply, State}.

terminate(_Reason, #state{changes_pid = Pid}) when is_pid(Pid) ->
    exit(Pid, kill);
terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, #state{}=State, _Extra) ->
    {ok, State}.

%% private functions

spawn_changes(Since) ->
    {Pid, _} = spawn_monitor(?MODULE, listen_for_changes, [Since]),
    Pid.

listen_for_changes(Since) ->
    CBFun = fun ?MODULE:changes_callback/2,
    Args = #changes_args{
        feed = "continuous",
        since = Since,
        heartbeat = true,
        filter = {default, main_only}
    },
    fabric:changes(dbname(), CBFun, Since, Args).

changes_callback(waiting_for_updates, Acc) ->
    {ok, Acc};
changes_callback(start, Since) ->
    {ok, Since};
changes_callback({stop, EndSeq, _Pending}, _) ->
    exit({seq, EndSeq});
changes_callback({change, {Change}}, _) ->
    case couch_util:get_value(id, Change) of
        <<"_design/", _/binary>> ->
            ok;
        DocId ->
            UserName = username(DocId),
            couch_log:debug("Invalidating cached credentials for ~s", [UserName]),
            ets_lru:remove(?CACHE, UserName)
    end,
    {ok, couch_util:get_value(seq, Change)};
changes_callback(timeout, Acc) ->
    {ok, Acc};
changes_callback({error, _}, EndSeq) ->
    exit({seq, EndSeq}).

load_user_from_db(UserName) ->
    try fabric:open_doc(dbname(), docid(UserName), [?ADMIN_CTX, ejson_body, conflicts]) of
	{ok, Doc} ->
	    {Props} = couch_doc:to_json_obj(Doc, []),
	    Props;
	_Else ->
	    couch_log:warning("no record of user ~s", [UserName]),
	    nil
    catch error:database_does_not_exist ->
	    nil
    end.

dbname() ->
    config:get("chttpd_auth", "authentication_db", "_users").

docid(UserName) ->
    <<"org.couchdb.user:", UserName/binary>>.

username(<<"org.couchdb.user:", UserName/binary>>) ->
    UserName.

ensure_auth_ddoc_exists(DbName, DDocId) ->
    case fabric:open_doc(DbName, DDocId, [?ADMIN_CTX, ejson_body]) of
    {not_found, _Reason} ->
        {ok, AuthDesign} = couch_auth_cache:auth_design_doc(DDocId),
        update_doc_ignoring_conflict(DbName, AuthDesign, [?ADMIN_CTX]);
    {ok, Doc} ->
        {Props} = couch_doc:to_json_obj(Doc, []),
        case couch_util:get_value(<<"validate_doc_update">>, Props, []) of
            ?AUTH_DB_DOC_VALIDATE_FUNCTION ->
                ok;
            _ ->
                Props1 = lists:keyreplace(<<"validate_doc_update">>, 1, Props,
                    {<<"validate_doc_update">>,
                    ?AUTH_DB_DOC_VALIDATE_FUNCTION}),
                update_doc_ignoring_conflict(DbName, couch_doc:from_json_obj({Props1}), [?ADMIN_CTX])
        end;
    {error, Reason} ->
        couch_log:notice("Failed to ensure auth ddoc ~s/~s exists for reason: ~p", [DbName, DDocId, Reason]),
        ok
    end,
    ok.

update_doc_ignoring_conflict(DbName, Doc, Options) ->
    try
        fabric:update_doc(DbName, Doc, Options)
    catch
        throw:conflict ->
            ok
    end.

maybe_validate_user_creds(nil) ->
    nil;
% throws if UserCreds includes a _conflicts member
% returns UserCreds otherwise
maybe_validate_user_creds(UserCreds) ->
    AllowConflictedUserDocs = config:get_boolean("chttpd_auth", "allow_conflicted_user_docs", false),
    case {couch_util:get_value(<<"_conflicts">>, UserCreds), AllowConflictedUserDocs} of
        {undefined, _} ->
            {ok, UserCreds, nil};
        {_, true} ->
            {ok, UserCreds, nil};
        {_ConflictList, false} ->
            throw({unauthorized,
                <<"User document conflicts must be resolved before the document",
                  " is used for authentication purposes.">>
            })
    end.
