%%-*- mode: erlang -*-

%% @doc The default name of a backend when one is not specified.
{mapping, "multi_backend.default", "riak_kv.multi_backend_default", [
  hidden
]}.

{translation,
 "riak_kv.multi_backend_default",
 fun(Conf) ->
  list_to_binary(cuttlefish:conf_get(["multi_backend", "default"], Conf))
 end}.

%% @doc Storage_backend specifies the Erlang module defining the storage
%% mechanism that will be used on this node.
{mapping, "multi_backend.$name.storage_backend", "riak_kv.multi_backend", [
  {default, bitcask},
  {datatype, {enum, [bitcask, leveldb, memory]}},
  hidden
]}.

{translation,
 "riak_kv.multi_backend",
 fun(Conf, Schema) ->
  GenerateSubConfig = fun(Name, Prefix, ProplistKey, ModuleName) ->
      BackendConfigName = ["multi_backend", Name],
      BackendConfigPrefix = BackendConfigName ++ [Prefix],
      SubConf = [ begin
          {lists:nthtail(2, Key), Value}
      end || {Key, Value} <- cuttlefish_variable:filter_by_prefix(BackendConfigPrefix, Conf)],

      case cuttlefish_generator:map(Schema, SubConf) of
        {error, _Phase, _Errors} ->
            cuttlefish:invalid(
              lists:flatten(io_lib:format(
                "Error processing multi_backend configuration for backend ~s", [Name])));
        BackendProplist ->
          Proplist = lists:foldl(
          fun(K, Acc) ->
            proplists:get_value(K, Acc, [])
          end,
          BackendProplist, ProplistKey),
          {ModuleName, Proplist}
      end
  end,
  %% group by $name into list, also cut the "multi_backend.$name" off every key
  BackendNames = cuttlefish_variable:fuzzy_matches(["multi_backend","$name","storage_backend"], Conf),
  %% for each in list, case statement on backend type
  Backends = [ begin
    BackendConfigName = ["multi_backend", Name],
    {BackendModule, BackendConfig} = case cuttlefish:conf_get(BackendConfigName ++ ["storage_backend"], Conf) of
      bitcask ->
        GenerateSubConfig(Name, "bitcask", [bitcask], riak_kv_bitcask_backend);
      leveldb ->
        GenerateSubConfig(Name, "leveldb", [eleveldb], riak_kv_eleveldb_backend);
      memory ->
        GenerateSubConfig(Name, "memory_backend", [riak_kv, memory_backend], riak_kv_memory_backend)
      end,
    {list_to_binary(Name),  BackendModule, BackendConfig}
  end || {"$name", Name} <- BackendNames],
  case Backends of
      [] -> throw(unset);
      _ -> Backends
  end
 end
}.
