 (ns datascript.impl.entity
-  (:require
-    [datascript.core :as dc]))
-
-(declare Entity touch)
+  (:refer-clojure :exclude [keys get])
+  (:require [#?(:cljs cljs.core :clj clojure.core) :as c]
+            [datascript.core :as dc]))
+
+(declare entity ->Entity equiv-entity lookup-entity touch)
 
 (defn- entid [db eid]
   (when (or (number? eid)

         (satisfies? dc/ISearch db)
         (satisfies? dc/IIndexAccess db)]}
  (when-let [e (entid db eid)]
    (Entity. db e false {})))

(defn- entity-attr [db a datoms]
  (if (dc/multival? db a)

                   v)))
             {} a->v))

(defn- datoms->cache [db datoms]
  (reduce (fn [acc part]
    (let [a (:a (first part))]
      (assoc acc a (entity-attr db a part))))
    {} (partition-by :a datoms)))

(defn touch [e]
  (when-not @(.-touched e)
    (when-let [datoms (not-empty (dc/-search (.-db e) [(.-eid e)]))]
      (vreset! (.-cache e) (->> datoms
                                (datoms->cache (.-db e))
                                (touch-components (.-db e))))
      (vreset! (.-touched e) true)))
  e)

#?(:cljs (do
           (goog/exportSymbol "datascript.impl.entity.Entity.prototype.get"       (.-get       (.-prototype Entity)))
           (goog/exportSymbol "datascript.impl.entity.Entity.prototype.has"       (.-has       (.-prototype Entity)))
           (goog/exportSymbol "datascript.impl.entity.Entity.prototype.forEach"   (.-forEach   (.-prototype Entity)))
           (goog/exportSymbol "datascript.impl.entity.Entity.prototype.key_set"   (.-key_set   (.-prototype Entity)))
           (goog/exportSymbol "datascript.impl.entity.Entity.prototype.value_set" (.-value_set (.-prototype Entity)))
           (goog/exportSymbol "datascript.impl.entity.Entity.prototype.entry_set" (.-entry_set (.-prototype Entity)))
           (goog/exportSymbol "datascript.impl.entity.Entity.prototype.keys"      (.-keys      (.-prototype Entity)))
           (goog/exportSymbol "datascript.impl.entity.Entity.prototype.values"    (.-values    (.-prototype Entity)))
           (goog/exportSymbol "datascript.impl.entity.Entity.prototype.entries"   (.-entries   (.-prototype Entity)))

           (goog/exportSymbol "cljs.core.ES6Iterator.prototype.next"        (.-next (.-prototype cljs.core/ES6Iterator)))
           (goog/exportSymbol "cljs.core.ES6EntriesIterator.prototype.next" (.-next (.-prototype cljs.core/ES6EntriesIterator)))
           ))
