 ;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 (ns containium.http-kit
+  "The namespace for starting and stopping HTTP Kit, and managing
+  boxes that contain ring apps."
   (:require [org.httpkit.server :refer (run-server)]
             [boxure.core :as boxure]))
 
 
 ;;; Ring app registry.
 
-(defrecord App [box handler-fn ring-conf])
+(defrecord RingApp [box handler-fn ring-conf])
 
 (def apps (atom {}))
 



(defmacro matcher
  [{:keys [host-regex context-path]} uri-sym server-name-sym]
  (let [host-test `(re-matches ~host-regex ~server-name-sym)
        context-test `(.startsWith ~uri-sym ~context-path)]

;;; Ring app registration.

(defn- clean-ring-conf
  "Updates the ring-conf, in order to ensure some properties of the values."
  [ring-conf]
  (update-in ring-conf [:context-path] #(when % (if (= (last %) \/) % (str % "/")))))


(defn upstart-box
  "Add a box holding a ring application. The box's project definition
  needs to have a :ring configuration inside the :boxure
  configuration. A required key is :handler-sym, which, when evaluated
  inside the box, should be the ring handler function. Optional keys
  are :context-path and :host-regex. The first acts as a filter for
  the first element(s) in the request URI, for example \"/api/v1/\".
  The second is a regular expression, which is matched against the
  server name of the request, for example \".*containium.com\"."
  [{:keys [name project] :as box}]
  (let [ring-conf (clean-ring-conf (-> project :boxure :ring))
        handler-fn (boxure/eval box (:handler-sym ring-conf))]
    (swap! apps assoc name (RingApp. box handler-fn ring-conf))
    (make-app)))


(defn remove-box
  "Removes a box's ring handler from the ring server."
  [{name :name}]
  (swap! apps dissoc name)
  (make-app))
