 (defn- execution-metrics
   "Get metrics based on executions.
   This should be done in a single pass, as there might
-  be a LOT of query executions in a normal instance
-  TODO: characterize by ad hoc vs cards"
-  []
-  (let [executions (db/select ['QueryExecution :executor_id :running_time :status])]
-    {:executions (count executions)
-     :by_status (frequencies (map :status executions))
-     :num_per_user (large-histogram executions :executor_id)
+  be a LOT of query executions in a normal instance."
+  ;; TODO - This looks dangerous, pulling the entire set of QueryExecutions into memory at once to calculate these metrics (!)
+  []
+  (let [executions (db/select [QueryExecution :executor_id :running_time :status])]
+    {:executions     (count executions)
+     :by_status      (frequencies (map :status executions))
+     :num_per_user   (large-histogram executions :executor_id)
      :num_by_latency (bin-latencies executions)}))
 
 

  "Get mes based on pulses
  TODO: characterize by non-user account emails, # emails"
  []
  (let [pulses (db/select ['Pulse :id :creator_id])
        pulsecards (db/select ['PulseCard :id :card_id :pulse_id])
        pulsechannels (db/select ['PulseChannel :channel_type :schedule_type])]
    {:pulses (count pulses)
     :pulse_types (frequencies (map :channel_type pulsechannels))
     :pulse_schedules (frequencies (map :schedule_type pulsechannels))
     :num_pulses_per_user (medium-histogram pulses :creator_id)
     :num_pulses_per_card (medium-histogram pulsecards :card_id)
     :num_cards_per_pulses (medium-histogram pulsecards :pulse_id)}))


(defn- label-metrics
  "Get metrics based on labels"
  []
  (let [labels (db/select 'Label)
        cardlabels (db/select ['CardLabel :card_id :label_id])]
    {:labels (count labels)
     :num_labels_per_card (micro-histogram cardlabels :card_id)
     :num_cards_per_label (medium-histogram cardlabels :label_id)}))


(defn- collection-metrics
  "Get metrics on collection usage"
  []
  (let [collections (db/select 'Collection)
        cards (db/select ['Card :collection_id])]
    {:collections (count collections)
     :cards_in_collections (count (filter (comp nil?) (map :collection_id cards)))
     :cards_not_in_collections (count (filter nil? (map :collection_id cards)))
     :num_cards_per_collection (medium-histogram cards :collection_id)}
    )
  )

;; Metadata Metrics
(defn- database-dims
  "characterize a database record"
  [database]
  {:total 1
   :analyzed (if (:is_full_sync database) 1 0)})

(defn- database-metrics
  "Get metrics based on databases"
  []
  (let [databases (db/select ['Database :id :is_full_sync])]
    {:databases (apply add-summaries (map database-dims databases))}))


(defn- table-metrics
  "Get metrics based on tables"
  []
  (let [tables (db/select ['Table :id :db_id :schema])]
    {:tables (count tables)
     :num_per_database (medium-histogram tables :db_id)
     :num_per_schema (medium-histogram tables :schema)}))


(defn- field-metrics
  "Get metrics based on fields"
  []
  (let [fields (db/select ['Field :id :table_id])]
    {:fields (count fields)
     :num_per_table (medium-histogram fields :table_id)}))

(defn- segment-metrics
  "Get metrics based on segments"
  []
  (let [segments (db/select ['Segment :id])]
    {:segments (count segments)}))


(defn- metric-metrics
  "Get metrics based on metrics"
  []
  (let [metrics (db/select ['Metric :id])]
    {:metrics (count metrics)}))


(defn- bin-latencies

  "generate a map of the usage stats for this instance"
  []
  (merge (instance-settings)
         {:uuid anonymous-id, :timestamp (java.util.Date.)}
         {:stats {:user       (user-metrics)
                  :question   (question-metrics)
                  :dashboard  (dashboard-metrics)
                  :database   (database-metrics)
                  :table      (table-metrics)
                  :field      (field-metrics)
                  :pulse      (pulse-metrics)
                  :segment    (segment-metrics)
                  :metric     (metric-metrics)
                  :group      (group-metrics)
                  :label      (label-metrics)
                  :collection (collection-metrics)
                  :execution  (execution-metrics)}}))


(defn- send-stats!
