text: % 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.
  %
  % Based on Bob Ippolitto's mochiglobal.erl
  
  -module(couch_log_config).
  
  
  -export([
      init/0,
      reconfigure/0,
      get/1
  ]).
  
  
  -define(MOD_NAME, couch_log_config_dyn).
  -define(ERL_FILE, "couch_log_config_dyn.erl").
  
  
  -spec init() -> ok.
  init() ->
      reconfigure().
  
  
  -spec reconfigure() -> ok.
  reconfigure() ->
      {ok, ?MOD_NAME, Bin} = compile:forms(forms(), [verbose, report_errors]),
      code:purge(?MOD_NAME),
      {module, ?MOD_NAME} = code:load_binary(?MOD_NAME, ?ERL_FILE, Bin),
      ok.
  
  
  -spec get(atom()) -> term().
  get(Key) ->
      ?MOD_NAME:get(Key).
  
  
  -spec entries() -> [string()].
  entries() ->
      [
          {level, "level", "info"},
          {level_int, "level", "info"},
          {max_message_size, "max_message_size", "16000"}
       ].
  
  
  -spec forms() -> [erl_syntax:syntaxTree()].
  forms() ->
      GetFunClauses = lists:map(fun({FunKey, CfgKey, Default}) ->
          FunVal = transform(FunKey, config:get("log", CfgKey, Default)),
          Patterns = [erl_syntax:abstract(FunKey)],
          Bodies = [erl_syntax:abstract(FunVal)],
          erl_syntax:clause(Patterns, none, Bodies)
      end, entries()),
  
      Statements = [
          % -module(?MOD_NAME)
          erl_syntax:attribute(
              erl_syntax:atom(module),
              [erl_syntax:atom(?MOD_NAME)]
          ),
  
          % -export([lookup/1]).
          erl_syntax:attribute(
              erl_syntax:atom(export),
              [erl_syntax:list([
                  erl_syntax:arity_qualifier(
                      erl_syntax:atom(get),
                      erl_syntax:integer(1))
              ])]
          ),
  
          % list(Key) -> Value.
          erl_syntax:function(erl_syntax:atom(get), GetFunClauses)
      ],
      [erl_syntax:revert(X) || X <- Statements].
  
  
  transform(level, LevelStr) ->
      couch_log_util:level_to_atom(LevelStr);
  
  transform(level_int, LevelStr) ->
      Level = couch_log_util:level_to_atom(LevelStr),
      couch_log_util:level_to_integer(Level);
  
  transform(max_message_size, SizeStr) ->
      try list_to_integer(SizeStr) of
          Size -> Size
      catch _:_ ->
          16000
      end.