(ns buddho.core.meta
  (:require [buddho.core.dhamma :as d]))

(def registry (atom {}))

(defn register-meta! [name & {:keys [aspects singleton-fn]}]
  (swap! registry update-in [:meta] assoc name
         {:aspects (or aspects {})
          :singleton (boolean singleton-fn)})
  (when singleton-fn
    (swap! registry update-in [:singletons] assoc name singleton-fn)))

(defn implement-meta! []
  (doseq [[name fun] (:singletons @registry)]
    (swap! registry update-in [:reified] assoc name (fun)))
  (doseq [[name meta] (:meta @registry)]
    (doseq [[stage asps] (:aspects meta)]
      (doseq [aspect asps]
        (d/register-aspect!
         (get-in @registry [:reified aspect])
         (vec (concat stage [name])))))))
