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

-export([enable_cluster/1, finish_cluster/1, add_node/1, receive_cookie/1]).
-export([is_cluster_enabled/0, has_cluster_system_dbs/1, cluster_system_dbs/0]).
-export([enable_single_node/1, is_single_node_enabled/1]).

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

require_admins(undefined, {undefined, undefined}) ->
    % no admin in CouchDB, no admin in request
    throw({error, "Cluster setup requires admin account to be configured"});
require_admins(_, _) ->
    ok.

require_node_count(undefined) ->
    throw({error, "Cluster setup requires node_count to be configured"});
require_node_count(_) ->
    ok.

error_local_bind_address() ->
    throw({error, "Cluster setup requires a remote bind_address (not 127.0.0.1 nor ::1)"}).

error_invalid_bind_address(InvalidBindAddress) ->
    throw(
        {error,
            io:format(
                "Setup requires a valid IP bind_address. " ++
                    "~p is invalid.",
                [InvalidBindAddress]
            )}
    ).

require_remote_bind_address(OldBindAddress, NewBindAddress) ->
    case {OldBindAddress, NewBindAddress} of
        {"127.0.0.1", undefined} -> error_local_bind_address();
        {_, <<"127.0.0.1">>} -> error_local_bind_address();
        {"::1", undefined} -> error_local_bind_address();
        {_, <<"::1">>} -> error_local_bind_address();
        {_, undefined} -> ok;
        {_, PresentNewBindAddress} -> require_valid_bind_address(PresentNewBindAddress)
    end.

require_valid_bind_address(BindAddress) ->
    ListBindAddress = binary_to_list(BindAddress),
    case inet_parse:address(ListBindAddress) of
        {ok, _} -> ok;
        {error, _} -> error_invalid_bind_address(ListBindAddress)
    end.

is_cluster_enabled() ->
    % bind_address != 127.0.0.1 AND admins != empty
    BindAddress = config:get("chttpd", "bind_address"),
    Admins = config:get("admins"),
    case {BindAddress, Admins} of
        {"127.0.0.1", _} -> false;
        {_, []} -> false;
        {_, _} -> true
    end.

is_single_node_enabled(Dbs) ->
    % admins != empty AND dbs exist
    Admins = config:get("admins"),
    HasDbs = has_cluster_system_dbs(Dbs),
    case {Admins, HasDbs} of
        {[], _} -> false;
        {_, false} -> false;
        {_, _} -> true
    end.

cluster_system_dbs() ->
    ["_users", "_replicator"].

has_cluster_system_dbs([]) ->
    true;
has_cluster_system_dbs([Db | Dbs]) ->
    case catch fabric:get_db_info(Db) of
        {ok, _} -> has_cluster_system_dbs(Dbs);
        _ -> false
    end.

enable_cluster(Options) ->
    case couch_util:get_value(remote_node, Options, undefined) of
        undefined ->
            enable_cluster_int(Options, is_cluster_enabled());
        _ ->
            enable_cluster_http(Options)
    end.

get_remote_request_options(Options) ->
    case couch_util:get_value(remote_current_user, Options, undefined) of
        undefined ->
            [];
        _ ->
            [
                {basic_auth, {
                    binary_to_list(couch_util:get_value(remote_current_user, Options)),
                    binary_to_list(couch_util:get_value(remote_current_password, Options))
                }}
            ]
    end.

enable_cluster_http(Options) ->
    % POST to nodeB/_setup
    RequestOptions = get_remote_request_options(Options),
    AdminUsername = couch_util:get_value(username, Options),
    AdminPasswordHash = config:get("admins", binary_to_list(AdminUsername)),

    Body = ?JSON_ENCODE(
        {[
            {<<"action">>, <<"enable_cluster">>},
            {<<"username">>, AdminUsername},
            {<<"password_hash">>, ?l2b(AdminPasswordHash)},
            {<<"bind_address">>, couch_util:get_value(bind_address, Options)},
            {<<"port">>, couch_util:get_value(port, Options)},
            {<<"node_count">>, couch_util:get_value(node_count, Options)}
        ]}
    ),

    Headers = [
        {"Content-Type", "application/json"}
    ],

    RemoteNode = couch_util:get_value(remote_node, Options),
    Port = get_port(couch_util:get_value(port, Options, 5984)),

    Url = binary_to_list(<<"http://", RemoteNode/binary, ":", Port/binary, "/_cluster_setup">>),

    case ibrowse:send_req(Url, Headers, post, Body, RequestOptions) of
        {ok, "201", _, _} ->
            ok;
        Else ->
            {error, Else}
    end.

enable_cluster_int(_Options, true) ->
    {error, cluster_enabled};
enable_cluster_int(Options, false) ->
    % if no admin in config and no admin in req -> error
    CurrentAdmins = config:get("admins"),
    NewCredentials = {
        proplists:get_value(username, Options),
        case proplists:get_value(password_hash, Options) of
            undefined -> proplists:get_value(password, Options);
            Pw -> Pw
        end
    },
    ok = require_admins(CurrentAdmins, NewCredentials),
    % if bind_address == 127.0.0.1 and no bind_address in req -> error
    CurrentBindAddress = config:get("chttpd", "bind_address"),
    NewBindAddress = proplists:get_value(bind_address, Options),
    ok = require_remote_bind_address(CurrentBindAddress, NewBindAddress),
    NodeCount = couch_util:get_value(node_count, Options),
    ok = require_node_count(NodeCount),
    Port = proplists:get_value(port, Options),

    setup_node(NewCredentials, NewBindAddress, NodeCount, Port),
    couch_log:debug("Enable Cluster: ~p~n", [couch_util:remove_sensitive_data(Options)]).

set_admin(Username, Password) ->
    config:set("admins", binary_to_list(Username), binary_to_list(Password), #{sensitive => true}),
    % 5 minutes
    wait_admins_to_be_hashed(60 * 5).

wait_admins_to_be_hashed(Tries) when is_integer(Tries), Tries > 0 ->
    case couch_passwords:get_unhashed_admins() of
        [] ->
            ok;
        [_ | _] ->
            timer:sleep(1000),
            couch_log:debug("Waiting for admins to be hashed. Seconds left: ~p", [Tries]),
            wait_admins_to_be_hashed(Tries - 1)
    end;
wait_admins_to_be_hashed(0) ->
    throw({setup_error, "Admin passwords could not be hashed"}).

setup_node(NewCredentials, NewBindAddress, NodeCount, Port) ->
    case NewCredentials of
        {undefined, undefined} ->
            ok;
        {Username, Password} ->
            set_admin(Username, Password)
    end,

    ok = require_valid_bind_address(NewBindAddress),
    case NewBindAddress of
        undefined ->
            config:set("chttpd", "bind_address", "0.0.0.0");
        NewBindAddress ->
            config:set("chttpd", "bind_address", binary_to_list(NewBindAddress))
    end,

    % for single node setups, set n=1, for larger setups, don’t
    % exceed n=3 as a default
    config:set_integer("cluster", "n", min(NodeCount, 3)),

    case Port of
        undefined ->
            ok;
        Port when is_binary(Port) ->
            config:set("chttpd", "port", binary_to_list(Port));
        Port when is_integer(Port) ->
            config:set_integer("chttpd", "port", Port)
    end.

finish_cluster(Options) ->
    % ensure that uuid is set
    couch_server:get_uuid(),

    ok = wait_connected(),
    ok = sync_admins(),
    ok = sync_uuid(),
    ok = sync_auth_secret(),
    Dbs = proplists:get_value(ensure_dbs_exist, Options, cluster_system_dbs()),
    finish_cluster_int(Dbs, has_cluster_system_dbs(Dbs)).

wait_connected() ->
    Nodes = other_nodes(),
    Result = test_util:wait(fun() ->
        case disconnected(Nodes) of
            [] -> ok;
            _ -> wait
        end
    end),
    case Result of
        timeout ->
            Reason = "Cluster setup timed out waiting for nodes to connect",
            throw({setup_error, Reason});
        ok ->
            ok
    end.

other_nodes() ->
    mem3:nodes() -- [node()].

disconnected(Nodes) ->
    lists:filter(
        fun(Node) ->
            case net_adm:ping(Node) of
                pong -> false;
                pang -> true
            end
        end,
        Nodes
    ).

sync_admins() ->
    ok = lists:foreach(
        fun({User, Pass}) ->
            sync_admin(User, Pass)
        end,
        config:get("admins")
    ).

sync_admin(User, Pass) ->
    sync_config("admins", User, Pass).

sync_uuid() ->
    Uuid = config:get("couchdb", "uuid"),
    sync_config("couchdb", "uuid", Uuid).

sync_auth_secret() ->
    Secret = config:get("chttpd_auth", "secret"),
    sync_config("chttpd_auth", "secret", Secret).

sync_config(Section, Key, Value) ->
    {Results, Errors} = rpc:multicall(
        other_nodes(),
        config,
        set,
        [Section, Key, Value]
    ),
    case validate_multicall(Results, Errors) of
        ok ->
            ok;
        error ->
            couch_log:error(
                "~p sync_admin results ~p errors ~p",
                [?MODULE, Results, Errors]
            ),
            Reason = "Cluster setup unable to sync admin passwords",
            throw({setup_error, Reason})
    end.

validate_multicall(Results, Errors) ->
    AllOk = lists:all(
        fun
            (ok) -> true;
            (_) -> false
        end,
        Results
    ),
    case AllOk andalso Errors == [] of
        true ->
            ok;
        false ->
            error
    end.

finish_cluster_int(_Dbs, true) ->
    {error, cluster_finished};
finish_cluster_int(Dbs, false) ->
    lists:foreach(fun fabric:create_db/1, Dbs).

enable_single_node(Options) ->
    % if no admin in config and no admin in req -> error
    CurrentAdmins = config:get("admins"),
    NewCredentials = {
        proplists:get_value(username, Options),
        case proplists:get_value(password_hash, Options) of
            undefined -> proplists:get_value(password, Options);
            Pw -> Pw
        end
    },
    ok = require_admins(CurrentAdmins, NewCredentials),
    % skip bind_address validation, anything is fine
    NewBindAddress = proplists:get_value(bind_address, Options),
    Port = proplists:get_value(port, Options),

    setup_node(NewCredentials, NewBindAddress, 1, Port),
    Dbs = proplists:get_value(ensure_dbs_exist, Options, cluster_system_dbs()),
    finish_cluster_int(Dbs, has_cluster_system_dbs(Dbs)),
    couch_log:debug("Enable Single Node: ~p~n", [Options]).

add_node(Options) ->
    add_node_int(Options, is_cluster_enabled()).

add_node_int(_Options, false) ->
    {error, cluster_not_enabled};
add_node_int(Options, true) ->
    couch_log:debug("add node_int: ~p~n", [couch_util:remove_sensitive_data(Options)]),
    ErlangCookie = erlang:get_cookie(),

    % POST to nodeB/_setup
    RequestOptions = [
        {basic_auth, {
            binary_to_list(proplists:get_value(username, Options)),
            binary_to_list(proplists:get_value(password, Options))
        }}
    ],

    Body = ?JSON_ENCODE(
        {[
            {<<"action">>, <<"receive_cookie">>},
            {<<"cookie">>, atom_to_binary(ErlangCookie, utf8)}
        ]}
    ),

    Headers = [
        {"Content-Type", "application/json"}
    ],

    Host = proplists:get_value(host, Options),
    Port = get_port(proplists:get_value(port, Options, 5984)),
    Name = proplists:get_value(name, Options, get_default_name(Port)),

    Url = binary_to_list(<<"http://", Host/binary, ":", Port/binary, "/_cluster_setup">>),

    case ibrowse:send_req(Url, Headers, post, Body, RequestOptions) of
        {ok, "201", _, _} ->
            % when done, PUT :5986/nodes/nodeB
            create_node_doc(Host, Name);
        Else ->
            Else
    end.

get_port(Port) when is_integer(Port) ->
    list_to_binary(integer_to_list(Port));
get_port(Port) when is_list(Port) ->
    list_to_binary(Port);
get_port(Port) when is_binary(Port) ->
    Port.

create_node_doc(Host, Name) ->
    {ok, Db} = couch_db:open_int(<<"_nodes">>, []),
    Doc = {[{<<"_id">>, <<Name/binary, "@", Host/binary>>}]},
    Options = [],
    CouchDoc = couch_doc:from_json_obj(Doc),

    couch_db:update_doc(Db, CouchDoc, Options).

get_default_name(Port) ->
    case Port of
        % shortcut for easier development
        <<"15984">> ->
            <<"node1">>;
        <<"25984">> ->
            <<"node2">>;
        <<"35984">> ->
            <<"node3">>;
        % by default, all nodes have the user `couchdb`
        _ ->
            <<"couchdb">>
    end.

receive_cookie(Options) ->
    Cookie = proplists:get_value(cookie, Options),
    erlang:set_cookie(node(), binary_to_atom(Cookie, latin1)).
