<commit_before>module Kemal
  # Kemal::Config stores all the configuration options for a Kemal application.
  # It's a singleton and you can access it like.
  #
  #   Kemal.config
  #
  class Config
    INSTANCE       = Config.new
    HANDLERS       = [] of HTTP::Handler
    ERROR_HANDLERS = {} of Int32 => HTTP::Server::Context, Exception -> String
    {% if flag?(:without_openssl) %}
    @ssl : Bool?
    {% else %}
    @ssl : OpenSSL::SSL::Context::Server?
    {% end %}

    property host_binding, ssl, port, env, public_folder, logging, running,
      always_rescue, serve_static : (Bool | Hash(String, Bool)), server, extra_options,
      shutdown_message

    def initialize
      @host_binding = "0.0.0.0"
      @port = 3000
      @env = "development"
      @serve_static = {"dir_listing" => false, "gzip" => true}
      @public_folder = "./public"
      @logging = true
      @logger = nil
      @error_handler = nil
      @always_rescue = true
      @server = uninitialized HTTP::Server
      @router_included = false
      @custom_handler_position = 4
      @default_handlers_setup = false
      @running = false
      @shutdown_message = true
    end

    def logger
      @logger.not_nil!
    end

    def logger=(logger : Kemal::BaseLogHandler)
      @logger = logger
    end

    def scheme
      ssl ? "https" : "http"
    end

    def clear
      @router_included = false
      @custom_handler_position = 4
      @default_handlers_setup = false
      HANDLERS.clear
    end

    def handlers
      HANDLERS
    end

    def add_handler(handler : HTTP::Handler | HTTP::WebSocketHandler)
      setup
      HANDLERS.insert @custom_handler_position, handler
      @custom_handler_position = @custom_handler_position + 1
    end

    def add_filter_handler(handler : HTTP::Handler)
      setup
      HANDLERS.insert HANDLERS.size - 1, handler
    end

    def error_handlers
      ERROR_HANDLERS
    end

    def add_error_handler(status_code, &handler : HTTP::Server::Context, Exception -> _)
      ERROR_HANDLERS[status_code] = ->(context : HTTP::Server::Context, error : Exception) { handler.call(context, error).to_s }
    end

    def extra_options(&@extra_options : OptionParser ->)
    end

    def setup
      unless @default_handlers_setup && @router_included
        setup_init_handler
        setup_log_handler
        setup_error_handler
        setup_static_file_handler
        @default_handlers_setup = true
        @router_included = true<commit_msg>Dont call setup in config#add_filter_handler. Fixes #338<commit_after>module Kemal
  # Kemal::Config stores all the configuration options for a Kemal application.
  # It's a singleton and you can access it like.
  #
  #   Kemal.config
  #
  class Config
    INSTANCE       = Config.new
    HANDLERS       = [] of HTTP::Handler
    ERROR_HANDLERS = {} of Int32 => HTTP::Server::Context, Exception -> String
    {% if flag?(:without_openssl) %}
    @ssl : Bool?
    {% else %}
    @ssl : OpenSSL::SSL::Context::Server?
    {% end %}

    property host_binding, ssl, port, env, public_folder, logging, running,
      always_rescue, serve_static : (Bool | Hash(String, Bool)), server, extra_options,
      shutdown_message

    def initialize
      @host_binding = "0.0.0.0"
      @port = 3000
      @env = "development"
      @serve_static = {"dir_listing" => false, "gzip" => true}
      @public_folder = "./public"
      @logging = true
      @logger = nil
      @error_handler = nil
      @always_rescue = true
      @server = uninitialized HTTP::Server
      @router_included = false
      @custom_handler_position = 4
      @default_handlers_setup = false
      @running = false
      @shutdown_message = true
    end

    def logger
      @logger.not_nil!
    end

    def logger=(logger : Kemal::BaseLogHandler)
      @logger = logger
    end

    def scheme
      ssl ? "https" : "http"
    end

    def clear
      @router_included = false
      @custom_handler_position = 4
      @default_handlers_setup = false
      HANDLERS.clear
    end

    def handlers
      HANDLERS
    end

    def add_handler(handler : HTTP::Handler | HTTP::WebSocketHandler)
      setup
      HANDLERS.insert @custom_handler_position, handler
      @custom_handler_position = @custom_handler_position + 1
    end

    def add_filter_handler(handler : HTTP::Handler)
      HANDLERS.insert HANDLERS.size - 1, handler
    end

    def error_handlers
      ERROR_HANDLERS
    end

    def add_error_handler(status_code, &handler : HTTP::Server::Context, Exception -> _)
      ERROR_HANDLERS[status_code] = ->(context : HTTP::Server::Context, error : Exception) { handler.call(context, error).to_s }
    end

    def extra_options(&@extra_options : OptionParser ->)
    end

    def setup
      unless @default_handlers_setup && @router_included
        setup_init_handler
        setup_log_handler
        setup_error_handler
        setup_static_file_handler
        @default_handlers_setup = true
        @router_included = true
{'fraction_non_alphanumeric': 0.09236625926668002, 'fraction_numerical': 0.006211180124223602, 'mean_word_length': 2.673289183222958, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7515760', 'n_tokens_mistral': 1586, 'n_tokens_neox': 1481, 'n_words': 366}