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

-include_lib("couch/include/couch_eunit.hrl").
-include_lib("eunit/include/eunit.hrl").
-include_lib("couch/include/couch_db.hrl").
-include("fabric2_test.hrl").
-include("fabric2.hrl").

fdb_tx_options_test_() ->
    {
        "Test setting default transaction options",
        setup,
        fun() ->
            meck:new(erlfdb, [passthrough]),
            % erlfdb, ctrace are all dependent apps for fabric. We make
            % sure to start them so when fabric is started during the test it
            % already has its dependencies
            test_util:start_couch([erlfdb, ctrace, fabric])
        end,
        fun(Ctx) ->
            meck:unload(),

            config:delete("fdb_tx_options", "size_limit", false),
            config:delete("fdb_tx_options", "max_retry_delay", false),
            config:delete("fdb_tx_options", "machine_id", false),
            config:delete("fdb_tx_options", "datacenter_id", false),

            test_util:stop_couch(Ctx)
        end,
        with([
            ?TDEF(options_take_effect, 15),
            ?TDEF(can_configure_options_at_runtime, 15),
            ?TDEF(can_apply_options_to_db_name_transactions),
            ?TDEF(can_apply_options_to_db_handle_transactions)
        ])
    }.

options_take_effect(_) ->
    ok = application:stop(fabric),

    % Try one of each type including some invalid values
    config:set("fdb_tx_options", "size_limit", "150000", false),
    config:set("fdb_tx_options", "max_retry_delay", "badness", false),
    config:set("fdb_tx_options", "machine_id", "123abc", false),
    TooLong = ["x" || _ <- lists:seq(1, 1000)],
    config:set("fdb_tx_options", "datacenter_id", TooLong, false),
    ok = application:start(fabric),

    DbName = ?tempdb(),
    {ok, Db} = fabric2_db:create(DbName, [?ADMIN_CTX]),
    ?assertError(
        {erlfdb_error, ?ERLFDB_TRANSACTION_TOO_LARGE},
        add_large_doc(Db, 200000)
    ),
    ok = fabric2_db:delete(DbName, [?ADMIN_CTX]).

can_configure_options_at_runtime(_) ->
    meck:expect(erlfdb, set_option, fun(Fdb, Option, Val) ->
        meck:passthrough([Fdb, Option, Val])
    end),

    meck:reset(erlfdb),

    config:set("fdb_tx_options", "size_limit", "150000", false),
    meck:wait(erlfdb, set_option, ['_', size_limit, 150000], 4000),

    DbName = ?tempdb(),

    {ok, Db} = fabric2_db:create(DbName, [?ADMIN_CTX]),
    ?assertError(
        {erlfdb_error, ?ERLFDB_TRANSACTION_TOO_LARGE},
        add_large_doc(Db, 200000)
    ),

    meck:reset(erlfdb),

    % Wait until after fabric2_server has updated the new fdb handle
    OldDbHandle = get(?PDICT_DB_KEY),
    config:delete("fdb_tx_options", "size_limit", false),
    test_util:wait(fun() ->
        case application:get_env(fabric, db) of
            {ok, OldDbHandle} -> wait;
            {ok, _} -> ok
        end
    end),
    erase(?PDICT_DB_KEY),

    {ok, Db1} = fabric2_db:open(DbName, [?ADMIN_CTX]),
    ?assertMatch({ok, _}, add_large_doc(Db1, 200000)),

    ok = fabric2_db:delete(DbName, [?ADMIN_CTX]).

can_apply_options_to_db_name_transactions(_) ->
    DbName = ?tempdb(),

    TxFun = fun(TxDb) ->
        #{tx := Tx} = TxDb,
        fabric2_fdb:create(TxDb, [?ADMIN_CTX]),
        erlfdb:wait(erlfdb:get(Tx, <<16#FF, "/primaryDatacenter">>))
    end,
    TxOpts = #{read_system_keys => <<>>},
    ?assertEqual(<<>>, fabric2_fdb:transactional(DbName, TxOpts, TxFun)),

    ok = fabric2_db:delete(DbName, [?ADMIN_CTX]).

can_apply_options_to_db_handle_transactions(_) ->
    DbName = ?tempdb(),
    {ok, Db} = fabric2_db:create(DbName, [?ADMIN_CTX]),

    TxFun = fun(TxDb) ->
        fabric2_db:update_doc(TxDb, large_doc(200000))
    end,
    TxOpts = #{size_limit => 150000},
    ?assertError(
        {erlfdb_error, ?ERLFDB_TRANSACTION_TOO_LARGE},
        fabric2_fdb:transactional(Db, TxOpts, TxFun)
    ),

    ok = fabric2_db:delete(DbName, [?ADMIN_CTX]).

add_large_doc(Db, Size) ->
    fabric2_db:update_doc(Db, large_doc(Size)).

large_doc(Size) ->
    #doc{
        id = fabric2_util:uuid(),
        body = {[{<<"x">>, crypto:strong_rand_bytes(Size)}]}
    }.
