%%-*- mode: erlang -*-
%% emqx_auth_pgsl config mapping

{mapping, "auth.pgsql.server", "emqx_auth_pgsql.server", [
  {default, {"127.0.0.1", 5432}},
  {datatype, [integer, ip, string]}
]}.

{mapping, "auth.pgsql.pool", "emqx_auth_pgsql.server", [
  {default, 8},
  {datatype, integer}
]}.

{mapping, "auth.pgsql.database", "emqx_auth_pgsql.server", [
  {datatype, string}
]}.

{mapping, "auth.pgsql.username", "emqx_auth_pgsql.server", [
  {default, ""},
  {datatype, string}
]}.

{mapping, "auth.pgsql.password", "emqx_auth_pgsql.server", [
  {default, ""},
  {datatype, string}
]}.

{mapping, "auth.pgsql.encoding", "emqx_auth_pgsql.server", [
  {default, utf8},
  {datatype, atom}
]}.

{mapping, "auth.pgsql.ssl", "emqx_auth_pgsql.server", [
  {default, off},
  {datatype, {enum, [on, off, true, false]}} %% FIXME: true/fasle is compatible with 4.0-4.2 version format, plan to delete in 5.0
]}.

{mapping, "auth.pgsql.ssl.tls_versions", "emqx_auth_pgsql.server", [
  {default, "tlsv1.3,tlsv1.2,tlsv1.1"},
  {datatype, string}
]}.

{mapping, "auth.pgsql.ssl.keyfile", "emqx_auth_pgsql.server", [
  {datatype, string}
]}.

{mapping, "auth.pgsql.ssl.certfile", "emqx_auth_pgsql.server", [
  {datatype, string}
]}.

{mapping, "auth.pgsql.ssl.cacertfile", "emqx_auth_pgsql.server", [
  {datatype, string}
]}.

{mapping, "auth.pgsql.ssl.verify", "emqx_auth_pgsql.server", [
  {default, false},
  {datatype, {enum, [true, false]}}
]}.

{mapping, "auth.pgsql.ssl.server_name_indication", "emqx_auth_pgsql.server", [
  {datatype, string}
]}.

%% FIXME: compatible with 4.0-4.2 version format, plan to delete in 5.0
{mapping, "auth.pgsql.ssl_opts.keyfile", "emqx_auth_pgsql.server", [
  {datatype, string}
]}.

%% FIXME: compatible with 4.0-4.2 version format, plan to delete in 5.0
{mapping, "auth.pgsql.ssl_opts.certfile", "emqx_auth_pgsql.server", [
  {datatype, string}
]}.

%% FIXME: compatible with 4.0-4.2 version format, plan to delete in 5.0
{mapping, "auth.pgsql.ssl_opts.cacertfile", "emqx_auth_pgsql.server", [
  {datatype, string}
]}.

%% FIXME: compatible with 4.0-4.2 version format, plan to delete in 5.0
{mapping, "auth.pgsql.ssl_opts.tls_versions", "emqx_auth_pgsql.server", [
  {default, "tlsv1.2"},
  {datatype, string}
]}.

{translation, "emqx_auth_pgsql.server", fun(Conf) ->
  {PgHost, PgPort} =
  case cuttlefish:conf_get("auth.pgsql.server", Conf) of
    {Ip, Port} -> {Ip, Port};
    S          -> case string:tokens(S, ":") of
                    [Domain]       -> {Domain, 5432};
                    [Domain, Port] -> {Domain, list_to_integer(Port)}
                  end
    end,
  Pool = cuttlefish:conf_get("auth.pgsql.pool", Conf),
  Username = cuttlefish:conf_get("auth.pgsql.username", Conf),
  Passwd = cuttlefish:conf_get("auth.pgsql.password", Conf, ""),
  DB = cuttlefish:conf_get("auth.pgsql.database", Conf),
  Encoding = cuttlefish:conf_get("auth.pgsql.encoding", Conf),

  Filter  = fun(Opts) -> [{K, V} || {K, V} <- Opts, V =/= undefined] end,
  SslOpts = fun(Prefix) ->
                Verify = case cuttlefish:conf_get(Prefix ++ ".verify", Conf, false) of
                             true -> verify_peer;
                             false -> verify_none
                         end,
                Filter([{keyfile,    cuttlefish:conf_get(Prefix ++ ".keyfile", Conf, undefined)},
                        {certfile,   cuttlefish:conf_get(Prefix ++ ".certfile", Conf, undefined)},
                        {cacertfile, cuttlefish:conf_get(Prefix ++ ".cacertfile", Conf, undefined)},
                        {verify,     Verify},
                        {server_name_indication, case cuttlefish:conf_get(Prefix ++ ".server_name_indication", Conf, undefined) of
                                                   "disable" -> disable;
                                                   SNI -> SNI
                                                 end},
                        {versions, [list_to_existing_atom(Value)
                                    || Value <- string:tokens(cuttlefish:conf_get(Prefix ++ ".tls_versions", Conf), " ,")]}])
            end,

  %% FIXME: compatible with 4.0-4.2 version format, plan to delete in 5.0
  Ssl = case cuttlefish:conf_get("auth.pgsql.ssl", Conf) of
          on -> [{ssl, true}, {ssl_opts, SslOpts("auth.pgsql.ssl")}];
          off -> [];
          true -> [{ssl, true}, {ssl_opts, SslOpts("auth.pgsql.ssl_opts")}];
          false -> []
        end,

  TempHost = case inet:parse_address(PgHost) of
      {ok, IpAddr} ->
          IpAddr;
      _ ->
          PgHost
  end,
  [{pool_size, Pool},
   {auto_reconnect, 1},
   {host, TempHost},
   {port, PgPort},
   {username, Username},
   {password, Passwd},
   {database, DB},
   {encoding, Encoding}] ++ Ssl
end}.

{mapping, "auth.pgsql.auth_query", "emqx_auth_pgsql.auth_query", [
  {datatype, string}
]}.

{mapping, "auth.pgsql.password_hash", "emqx_auth_pgsql.password_hash", [
  {datatype, string}
]}.

{mapping, "auth.pgsql.pbkdf2_macfun", "emqx_auth_pgsql.pbkdf2_macfun", [
  {datatype, atom}
]}.

{mapping, "auth.pgsql.pbkdf2_iterations", "emqx_auth_pgsql.pbkdf2_iterations", [
  {datatype, integer}
]}.

{mapping, "auth.pgsql.pbkdf2_dklen", "emqx_auth_pgsql.pbkdf2_dklen", [
  {datatype, integer}
]}.

{mapping, "auth.pgsql.super_query", "emqx_auth_pgsql.super_query", [
  {datatype, string}
]}.

{mapping, "auth.pgsql.acl_query", "emqx_auth_pgsql.acl_query", [
  {datatype, string}
]}.

{translation, "emqx_auth_pgsql.password_hash", fun(Conf) ->
  HashValue = cuttlefish:conf_get("auth.pgsql.password_hash", Conf),
  case string:tokens(HashValue, ",") of
    [Hash]           -> list_to_atom(Hash);
    [Prefix, Suffix] -> {list_to_atom(Prefix), list_to_atom(Suffix)};
    [Hash, MacFun, Iterations, Dklen] -> {list_to_atom(Hash), list_to_atom(MacFun), list_to_integer(Iterations), list_to_integer(Dklen)};
    _                -> plain
  end
end}.
