%%-*- mode: erlang -*-
%% emqx_auth_mysql config mapping
{mapping, "auth.mysql.server", "emqx_auth_mysql.server", [
  {default, {"127.0.0.1", 3306}},
  {datatype, [integer, ip, string]}
]}.

{mapping, "auth.mysql.pool", "emqx_auth_mysql.server", [
  {default, 8},
  {datatype, integer}
]}.

{mapping, "auth.mysql.username", "emqx_auth_mysql.server", [
  {default, ""},
  {datatype, string}
]}.

{mapping, "auth.mysql.password", "emqx_auth_mysql.server", [
  {default, ""},
  {datatype, string}
]}.

{mapping, "auth.mysql.database", "emqx_auth_mysql.server", [
  {default, "mqtt"},
  {datatype, string}
]}.

{mapping, "auth.mysql.query_timeout", "emqx_auth_mysql.server", [
  {default, ""},
  {datatype, string}
]}.

{mapping, "auth.mysql.ssl", "emqx_auth_mysql.server", [
  {default, off},
  {datatype, flag}
]}.

{mapping, "auth.mysql.ssl.cafile", "emqx_auth_mysql.server", [
  {datatype, string}
]}.

{mapping, "auth.mysql.ssl.cacertfile", "emqx_auth_mysql.server", [
  {datatype, string}
]}.

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

{mapping, "auth.mysql.ssl.keyfile", "emqx_auth_mysql.server", [
  {datatype, string}
]}.

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

{mapping, "auth.mysql.ssl.server_name_indication", "emqx_auth_mysql.server", [
  {datatype, string}
]}.

{translation, "emqx_auth_mysql.server", fun(Conf) ->
  {MyHost, MyPort} =
  case cuttlefish:conf_get("auth.mysql.server", Conf) of
    {Ip, Port} -> {Ip, Port};
    S          -> case string:tokens(S, ":") of
                    [Domain]       -> {Domain, 3306};
                    [Domain, Port] -> {Domain, list_to_integer(Port)}
                  end
    end,
  Pool = cuttlefish:conf_get("auth.mysql.pool", Conf),
  Username = cuttlefish:conf_get("auth.mysql.username", Conf),
  Passwd = cuttlefish:conf_get("auth.mysql.password", Conf),
  DB = cuttlefish:conf_get("auth.mysql.database", Conf),
  Timeout = case cuttlefish:conf_get("auth.mysql.query_timeout", Conf) of
                "" -> 300000;
                Duration ->
                    case cuttlefish_duration:parse(Duration, ms) of
                      {error, Reason} -> error(Reason);
                      Ms when is_integer(Ms) -> Ms
                  end
            end,
  Options = [{pool_size, Pool},
             {auto_reconnect, 1},
             {host, MyHost},
             {port, MyPort},
             {user, Username},
             {password, Passwd},
             {database, DB},
             {encoding, utf8},
             {query_timeout, Timeout},
             {keep_alive, true}],
  Filter  = fun(Opts) -> [{K, V} || {K, V} <- Opts, V =/= undefined] end,
  Options1 =
      case cuttlefish:conf_get("auth.mysql.ssl", Conf) of
            true ->
                %% FIXME: compatible with 4.0-4.2 version format, plan to delete in 5.0
                CA = cuttlefish:conf_get(
                        "auth.mysql.ssl.cacertfile", Conf,
                        cuttlefish:conf_get("auth.mysql.ssl.cafile", Conf, undefined)
                     ),
                Cert = cuttlefish:conf_get("auth.mysql.ssl.certfile", Conf, undefined),
                Key = cuttlefish:conf_get("auth.mysql.ssl.keyfile", Conf, undefined),
                Verify = case cuttlefish:conf_get("auth.mysql.ssl.verify", Conf, false) of
                             true -> verify_peer;
                             false -> verify_none
                         end,
                SNI = case cuttlefish:conf_get("auth.mysql.ssl.server_name_indication", Conf, undefined) of
                        "disable" -> disable;
                        SNI0 -> SNI0
                      end,
                Options ++ [{ssl, Filter([{server_name_indication, SNI},
                                          {cacertfile, CA},
                                          {certfile, Cert},
                                          {keyfile, Key},
                                          {verify, Verify}
                                         ])
                            }];
            _ ->
                Options
      end,
  case inet:parse_address(MyHost) of
      {ok, IpAddr} when tuple_size(IpAddr) =:= 8 ->
          [{tcp_options, [inet6]} | Options1];
      _ ->
          Options1
  end
end}.

{mapping, "auth.mysql.auth_query", "emqx_auth_mysql.auth_query", [
  {datatype, string}
]}.

{mapping, "auth.mysql.password_hash", "emqx_auth_mysql.password_hash", [
  {datatype, string}
]}.

{mapping, "auth.mysql.super_query", "emqx_auth_mysql.super_query", [
  {datatype, string}
]}.

{mapping, "auth.mysql.acl_query", "emqx_auth_mysql.acl_query", [
  {datatype, string}
]}.

{translation, "emqx_auth_mysql.password_hash", fun(Conf) ->
  HashValue = cuttlefish:conf_get("auth.mysql.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}.
