%%-*- mode: erlang -*-
%% emqx_coap config mapping
{mapping, "coap.bind.udp.$number", "emqx_coap.bind_udp", [
  {datatype, ip},
  {default, "0.0.0.0:5683"}
]}.

{mapping, "coap.enable_stats", "emqx_coap.enable_stats", [
  {datatype, flag}
]}.

{mapping, "coap.bind.dtls.$number", "emqx_coap.bind_dtls", [
  {datatype, ip},
  {default, "0.0.0.0:5684"}
]}.

{mapping, "coap.dtls.keyfile", "emqx_coap.dtls_opts", [
  {datatype, string}
]}.

{mapping, "coap.dtls.certfile", "emqx_coap.dtls_opts", [
  {datatype, string}
]}.

{mapping, "coap.dtls.verify", "emqx_coap.dtls_opts", [
  {default, verify_none},
  {datatype, {enum, [verify_none, verify_peer]}}
]}.

{mapping, "coap.dtls.cacertfile", "emqx_coap.dtls_opts", [
  {datatype, string}
]}.

{mapping, "coap.dtls.fail_if_no_peer_cert", "emqx_coap.dtls_opts", [
  {datatype, {enum, [true, false]}}
]}.

{mapping, "coap.dtls.ciphers", "emqx_coap.dtls_opts", [
  {datatype, string}
]}.

{translation, "emqx_coap.bind_udp", fun(Conf) ->
  Options = cuttlefish_variable:filter_by_prefix("coap.bind.udp", Conf),
  lists:map(fun({_, Bind}) ->
    {Ip, Port} = cuttlefish_datatypes:from_string(Bind, ip),
    Opts = case inet:parse_address(Ip) of
    {ok, {_,_,_,_} = Address} ->
      [inet, {ip, Address}];
    {ok, {_,_,_,_,_,_,_,_} = Address} ->
      [inet6, {ip, Address}]
    end,
    {Port, Opts}
  end, Options)
end}.

{translation, "emqx_coap.bind_dtls", fun(Conf) ->
  Options = cuttlefish_variable:filter_by_prefix("coap.bind.dtls", Conf),
  lists:map(fun({_, Bind}) ->
    {Ip, Port} = cuttlefish_datatypes:from_string(Bind, ip),
    Opts = case inet:parse_address(Ip) of
    {ok, {_,_,_,_} = Address} ->
      [inet, {ip, Address}];
    {ok, {_,_,_,_,_,_,_,_} = Address} ->
      [inet6, {ip, Address}]
    end,
    {Port, Opts}
  end, Options)
end}.

{translation, "emqx_coap.dtls_opts", fun(Conf) ->
  Filter  = fun(Opts) -> [{K, V} || {K, V} <- Opts, V =/= undefined] end,

  %% Ciphers
  SplitFun = fun(undefined) -> undefined; (S) -> string:tokens(S, ",") end,
  Ciphers =
      case cuttlefish:conf_get("coap.dtls.ciphers", Conf, undefined) of
          undefined ->
              lists:append([ssl:cipher_suites(all, V, openssl) || V <- ['dtlsv1.2', 'dtlsv1']]);
          C ->
              SplitFun(C)
      end,

  Filter([{verify, cuttlefish:conf_get("coap.dtls.verify", Conf, undefined)},
          {keyfile, cuttlefish:conf_get("coap.dtls.keyfile", Conf, undefined)},
          {certfile, cuttlefish:conf_get("coap.dtls.certfile", Conf, undefined)},
          {cacertfile, cuttlefish:conf_get("coap.dtls.cacertfile", Conf, undefined)},
          {fail_if_no_peer_cert, cuttlefish:conf_get("coap.dtls.fail_if_no_peer_cert", Conf, undefined)},
          {ciphers, Ciphers}])
end}.

