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

-export([open/2,create/2,delete/2,all_databases/0,get_version/0]).
-export([init/1, handle_call/3,sup_start_link/0]).
-export([handle_cast/2,code_change/3,handle_info/2,terminate/2]).
-export([dev_start/0,is_admin/2,has_admins/0,get_stats/0]).

-include("couch_db.hrl").

-record(server,{
    root_dir = [],
    dbname_regexp,
    max_dbs_open=100,
    dbs_open=0,
    start_time=""
    }).

dev_start() ->
    couch:stop(),
    up_to_date = make:all([load, debug_info]),
    couch:start().

get_version() ->
    Apps = application:loaded_applications(),
    case lists:keysearch(couch, 1, Apps) of
    {value, {_, _, Vsn}} ->
        Vsn;
    false ->
        "0.0.0"
    end.

get_stats() ->
    {ok, #server{start_time=Time,dbs_open=Open}} =
            gen_server:call(couch_server, get_server),
    [{start_time, ?l2b(Time)}, {dbs_open, Open}].

sup_start_link() ->
    gen_server:start_link({local, couch_server}, couch_server, [], []).

open(DbName, Options) ->
    case gen_server:call(couch_server, {open, DbName, Options}, infinity) of
    {ok, Db} ->
        Ctx = couch_util:get_value(user_ctx, Options, #user_ctx{}),
        {ok, Db#db{user_ctx=Ctx}};
    Error ->
        Error
    end.

create(DbName, Options) ->
    case gen_server:call(couch_server, {create, DbName, Options}, infinity) of
    {ok, Db} ->
        Ctx = couch_util:get_value(user_ctx, Options, #user_ctx{}),
        {ok, Db#db{user_ctx=Ctx}};
    Error ->
        Error
    end.

delete(DbName, Options) ->
    gen_server:call(couch_server, {delete, DbName, Options}, infinity).

check_dbname(#server{dbname_regexp=RegExp}, DbName) ->
    case re:run(DbName, RegExp, [{capture, none}]) of
    nomatch ->
        case DbName of
            "_users" -> ok;
            _Else ->
                {error, illegal_database_name}
            end;
    match ->
        ok
    end.

is_admin(User, ClearPwd) ->
    case couch_config:get("admins", User) of
    "-hashed-" ++ HashedPwdAndSalt ->
        [HashedPwd, Salt] = string:tokens(HashedPwdAndSalt, ","),
        couch_util:to_hex(crypto:sha(ClearPwd ++ Salt)) == HashedPwd;
    _Else ->
        false
    end.

has_admins() ->
    couch_config:get("admins") /= [].

get_full_filename(Server, DbName) ->
    filename:join([Server#server.root_dir, "./" ++ DbName ++ ".couch"]).

hash_admin_passwords() ->
    hash_admin_passwords(true).

hash_admin_passwords(Persist) ->
    lists:foreach(
        fun({_User, "-hashed-" ++ _}) ->
            ok; % already hashed
        ({User, ClearPassword}) ->
            Salt = ?b2l(couch_uuids:random()),
            Hashed = couch_util:to_hex(crypto:sha(ClearPassword ++ Salt)),
            couch_config:set("admins",
                User, "-hashed-" ++ Hashed ++ "," ++ Salt, Persist)
        end, couch_config:get("admins")).

init([]) ->
    % read config and register for configuration changes

    % just stop if one of the config settings change. couch_server_sup
    % will restart us and then we will pick up the new settings.

    RootDir = couch_config:get("couchdb", "database_dir", "."),
    MaxDbsOpen = list_to_integer(
            couch_config:get("couchdb", "max_dbs_open")),
    Self = self(),
    ok = couch_config:register(
        fun("couchdb", "database_dir") ->
            exit(Self, config_change)
        end),
    ok = couch_config:register(
        fun("couchdb", "max_dbs_open", Max) ->
            gen_server:call(couch_server,
                    {set_max_dbs_open, list_to_integer(Max)})
        end),
    ok = couch_file:init_delete_dir(RootDir),
    hash_admin_passwords(),
    ok = couch_config:register(
        fun("admins", _Key, _Value, Persist) ->
            % spawn here so couch_config doesn't try to call itself
            spawn(fun() -> hash_admin_passwords(Persist) end)
        end, false),
    {ok, RegExp} = re:compile("^[a-z][a-z0-9\\_\\$()\\+\\-\\/]*$"),
    ets:new(couch_dbs_by_name, [set, private, named_table]),
    ets:new(couch_dbs_by_pid, [set, private, named_table]),
    ets:new(couch_dbs_by_lru, [ordered_set, private, named_table]),
    ets:new(couch_sys_dbs, [set, private, named_table]),
    process_flag(trap_exit, true),
    {ok, #server{root_dir=RootDir,
                dbname_regexp=RegExp,
                max_dbs_open=MaxDbsOpen,
                start_time=httpd_util:rfc1123_date()}}.

terminate(_Reason, _Srv) ->
    [couch_util:shutdown_sync(Pid) || {_, {Pid, _LruTime}} <-
            ets:tab2list(couch_dbs_by_name)],
    ok.

all_databases() ->
    {ok, #server{root_dir=Root}} = gen_server:call(couch_server, get_server),
    NormRoot = couch_util:normpath(Root),
    Filenames =
    filelib:fold_files(Root, "^[a-z0-9\\_\\$()\\+\\-]*[\\.]couch$", true,
        fun(Filename, AccIn) ->
            NormFilename = couch_util:normpath(Filename),
            case NormFilename -- NormRoot of
            [$/ | RelativeFilename] -> ok;
            RelativeFilename -> ok
            end,
            [list_to_binary(filename:rootname(RelativeFilename, ".couch")) | AccIn]
        end, []),
    {ok, Filenames}.


maybe_close_lru_db(#server{dbs_open=NumOpen, max_dbs_open=MaxOpen}=Server)
        when NumOpen < MaxOpen ->
    {ok, Server};
maybe_close_lru_db(#server{dbs_open=NumOpen}=Server) ->
    % must free up the lru db.
    case try_close_lru(now()) of
    ok ->
        {ok, Server#server{dbs_open=NumOpen - 1}};
    Error -> Error
    end.

try_close_lru(StartTime) ->
    LruTime = get_lru(),
    if LruTime > StartTime ->
        % this means we've looped through all our opened dbs and found them
        % all in use.
        {error, all_dbs_active};
    true ->
        [{_, DbName}] = ets:lookup(couch_dbs_by_lru, LruTime),
        [{_, {opened, MainPid, LruTime}}] = ets:lookup(couch_dbs_by_name, DbName),
        case couch_db:is_idle(MainPid) of
        true ->
            couch_util:shutdown_sync(MainPid),
            true = ets:delete(couch_dbs_by_lru, LruTime),
            true = ets:delete(couch_dbs_by_name, DbName),
            true = ets:delete(couch_dbs_by_pid, MainPid),
            true = ets:delete(couch_sys_dbs, DbName),
            ok;
        false ->
            % this still has referrers. Go ahead and give it a current lru time
            % and try the next one in the table.
            NewLruTime = now(),
            true = ets:insert(couch_dbs_by_name, {DbName, {opened, MainPid, NewLruTime}}),
            true = ets:insert(couch_dbs_by_pid, {MainPid, DbName}),
            true = ets:delete(couch_dbs_by_lru, LruTime),
            true = ets:insert(couch_dbs_by_lru, {NewLruTime, DbName}),
            try_close_lru(StartTime)
        end
    end.

get_lru() ->
    get_lru(ets:first(couch_dbs_by_lru)).

get_lru(LruTime) ->
    [{LruTime, DbName}] = ets:lookup(couch_dbs_by_lru, LruTime),
    case ets:member(couch_sys_dbs, DbName) of
    false ->
        LruTime;
    true ->
        [{_, {opened, MainPid, _}}] = ets:lookup(couch_dbs_by_name, DbName),
        case couch_db:is_idle(MainPid) of
        true ->
            LruTime;
        false ->
            get_lru(ets:next(couch_dbs_by_lru, LruTime))
        end
    end.

open_async(Server, From, DbName, Filepath, Options) ->
    Parent = self(),
    Opener = spawn_link(fun() ->
            Res = couch_db:start_link(DbName, Filepath, Options),
            gen_server:call(
                Parent, {open_result, DbName, Res, Options}, infinity
            ),
            unlink(Parent),
            case Res of
            {ok, DbReader} ->
                unlink(DbReader);
            _ ->
                ok
            end
        end),
    true = ets:insert(couch_dbs_by_name, {DbName, {opening, Opener, [From]}}),
    true = ets:insert(couch_dbs_by_pid, {Opener, DbName}),
    DbsOpen = case lists:member(sys_db, Options) of
    true ->
        true = ets:insert(couch_sys_dbs, {DbName, true}),
        Server#server.dbs_open;
    false ->
        Server#server.dbs_open + 1
    end,
    Server#server{dbs_open = DbsOpen}.

handle_call({set_max_dbs_open, Max}, _From, Server) ->
    {reply, ok, Server#server{max_dbs_open=Max}};
handle_call(get_server, _From, Server) ->
    {reply, {ok, Server}, Server};
handle_call({open_result, DbName, {ok, OpenedDbPid}, Options}, _From, Server) ->
    link(OpenedDbPid),
    [{DbName, {opening,Opener,Froms}}] = ets:lookup(couch_dbs_by_name, DbName),
    lists:foreach(fun({FromPid,_}=From) ->
        gen_server:reply(From,
                catch couch_db:open_ref_counted(OpenedDbPid, FromPid))
    end, Froms),
    LruTime = now(),
    true = ets:insert(couch_dbs_by_name,
            {DbName, {opened, OpenedDbPid, LruTime}}),
    true = ets:delete(couch_dbs_by_pid, Opener),
    true = ets:insert(couch_dbs_by_pid, {OpenedDbPid, DbName}),
    true = ets:insert(couch_dbs_by_lru, {LruTime, DbName}),
    case lists:member(create, Options) of
    true ->
        couch_db_update_notifier:notify({created, DbName});
    false ->
        ok
    end,
    {reply, ok, Server};
handle_call({open_result, DbName, Error, Options}, _From, Server) ->
    [{DbName, {opening,Opener,Froms}}] = ets:lookup(couch_dbs_by_name, DbName),
    lists:foreach(fun(From) ->
        gen_server:reply(From, Error)
    end, Froms),
    true = ets:delete(couch_dbs_by_name, DbName),
    true = ets:delete(couch_dbs_by_pid, Opener),
    DbsOpen = case lists:member(sys_db, Options) of
    true ->
        true = ets:delete(couch_sys_dbs, DbName),
        Server#server.dbs_open;
    false ->
        Server#server.dbs_open - 1
    end,
    {reply, ok, Server#server{dbs_open = DbsOpen}};
handle_call({open, DbName, Options}, {FromPid,_}=From, Server) ->
    LruTime = now(),
    case ets:lookup(couch_dbs_by_name, DbName) of
    [] ->
        open_db(DbName, Server, Options, From);
    [{_, {opening, Opener, Froms}}] ->
        true = ets:insert(couch_dbs_by_name, {DbName, {opening, Opener, [From|Froms]}}),
        {noreply, Server};
    [{_, {opened, MainPid, PrevLruTime}}] ->
        true = ets:insert(couch_dbs_by_name, {DbName, {opened, MainPid, LruTime}}),
        true = ets:delete(couch_dbs_by_lru, PrevLruTime),
        true = ets:insert(couch_dbs_by_lru, {LruTime, DbName}),
        {reply, couch_db:open_ref_counted(MainPid, FromPid), Server}
    end;
handle_call({create, DbName, Options}, From, Server) ->
    case ets:lookup(couch_dbs_by_name, DbName) of
    [] ->
        open_db(DbName, Server, [create | Options], From);
    [_AlreadyRunningDb] ->
        {reply, file_exists, Server}
    end;
handle_call({delete, DbName, _Options}, _From, Server) ->
    DbNameList = binary_to_list(DbName),
    case check_dbname(Server, DbNameList) of
    ok ->
        FullFilepath = get_full_filename(Server, DbNameList),
        UpdateState =
        case ets:lookup(couch_dbs_by_name, DbName) of
        [] -> false;
        [{_, {opening, Pid, Froms}}] ->
            couch_util:shutdown_sync(Pid),
            true = ets:delete(couch_dbs_by_name, DbName),
            true = ets:delete(couch_dbs_by_pid, Pid),
            [gen_server:send_result(F, not_found) || F <- Froms],
            true;
        [{_, {opened, Pid, LruTime}}] ->
            couch_util:shutdown_sync(Pid),
            true = ets:delete(couch_dbs_by_name, DbName),
            true = ets:delete(couch_dbs_by_pid, Pid),
            true = ets:delete(couch_dbs_by_lru, LruTime),
            true
        end,
        Server2 = case UpdateState of
        true ->
            DbsOpen = case ets:member(couch_sys_dbs, DbName) of
            true ->
                true = ets:delete(couch_sys_dbs, DbName),
                Server#server.dbs_open;
            false ->
                Server#server.dbs_open - 1
            end,
            Server#server{dbs_open = DbsOpen};
        false ->
            Server
        end,

        %% Delete any leftover .compact files.  If we don't do this a subsequent
        %% request for this DB will try to open the .compact file and use it.
        couch_file:delete(Server#server.root_dir, FullFilepath ++ ".compact"),

        case couch_file:delete(Server#server.root_dir, FullFilepath) of
        ok ->
            couch_db_update_notifier:notify({deleted, DbName}),
            {reply, ok, Server2};
        {error, enoent} ->
            {reply, not_found, Server2};
        Else ->
            {reply, Else, Server2}
        end;
    Error ->
        {reply, Error, Server}
    end.

handle_cast(Msg, _Server) ->
    exit({unknown_cast_message, Msg}).

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.
    
handle_info({'EXIT', _Pid, config_change}, Server) ->
    {noreply, shutdown, Server};
handle_info(Error, _Server) ->
    ?LOG_ERROR("Unexpected message, restarting couch_server: ~p", [Error]),
    exit(kill).

open_db(DbName, Server, Options, From) ->
    DbNameList = binary_to_list(DbName),
    case check_dbname(Server, DbNameList) of
    ok ->
        Filepath = get_full_filename(Server, DbNameList),
        case lists:member(sys_db, Options) of
        true ->
            {noreply, open_async(Server, From, DbName, Filepath, Options)};
        false ->
            case maybe_close_lru_db(Server) of
            {ok, Server2} ->
                {noreply, open_async(Server2, From, DbName, Filepath, Options)};
            CloseError ->
                {reply, CloseError, Server}
            end
        end;
     Error ->
        {reply, Error, Server}
     end.
