(ns emptyhead.thought.crud
  "Implements CRUD operations on thoughts.
  Since thoughts are ideas, 'missing' operations here are implemented in [[emptyhead.idea.crud]]."
  (:require [emptyhead.idea.protocol :as prtc]
            [emptyhead.idea.crud :as idea]
            [emptyhead.idea.property :as prop]
            [emptyhead.contract.eval :as contract]))

(defn make-thought
  "Helper function to make thought object.
  You may want `register-thought!` instead."
  [operator & {:keys [data ext-contract ext-stages transient]
               :or {data {} ext-contract {}
                    ext-stages [[:thought operator]]
                    transient true}}]
  (hash-map :operator operator
            :data data
            :ext-contract ext-contract
            :ext-stages ext-stages
            :return {}
            :transient (not (false? transient))))

(defn register-thought!
  "Create a thought and register it in the state.
  Returns a reference to the created thought."
  [operator & {:keys [data ext-contract ext-stages transient]
               :as args}]
    (idea/have-idea!
     :prefix (str "thought_" (name operator) "_")
     :properties [[:thought]]
     :data (make-thought operator args)))

(defn contract
  "Get the extension contract of a `thought`.
  Returns the contract."
  [thought]
  (prtc/val-fn :ext-contract thought))

(defn stages
  "Get the extension stages of a `thought`.
  Returns the list of stages."
  [thought]
  (prtc/val-fn :ext-stages thought))

(defn operator
  "Get the operator id of a `thought`.
  Returns the operator keyword."
  [thought]
  (prtc/val-fn :operator thought))
