     #'do-send-event
 
     "snapshot-event"
-    #'do-snapshot-event
+    #'do-backlog-events
 
     "log-reply"
-    #'do-log-reply
+    #'do-backlog-events
 
     :unknown-type
     ;; (fn [session msg]

      (do ;; something's wrong
        (println msg)))))

(defn log-messages
  "Log message datas to file."
  [session event-datas]
  (let [w (-> session :state deref :logger :writer)]
    (binding [*out* w]
      (doseq [m event-datas]
        (println (json/generate-string {:hl-type "message"
                                        :data m}))))
    (.flush w)))

(defn do-send-event
  "Log a single new message to file."
  [session msg]
  (log-messages session [(get-in msg [:data])]))

(defn oldest-msg-id
  [msgs]
  (:id (max-1 (fn compare-times [x y]
                ;; Reverse sort, get msg with min time
                (- (:time y) (:time x)))
              msgs)))

(defn ask-for-backlog
  [session before-id]
  (println "Asking for backlog before" before-id)
  (send-message session
                {:type "log"
                 :data {:n 1000
                        :before before-id}}))

(defn do-snapshot-event
  "Log an entire snapshot to file."
  [session msg]
  (let [recent-log (get-in msg [:data :log])]
    (log-messages session recent-log)
    ;; Start downloading entire room history
    (println "Switching to full catchup mode!")
    ;; Should maybe check if lifecycle is :waiting-for-snapshot ?
    (alter (:state session) assoc-in [:logger :lifecycle] :full-catchup)
    (ask-for-backlog session (oldest-msg-id recent-log))))

(defn do-log-reply
  "Write backlog to file, ask for more if possible."
  [session msg]
  (let [recent-log (get-in msg [:data :log])]
    (if (empty? recent-log)
      (do (println "All caught up, no more backlog. Now just tailing.")
          (alter (:state session) assoc-in [:logger :lifecycle] :tailing))
      (do (log-messages session recent-log)
          (ask-for-backlog session (oldest-msg-id recent-log))))))

(def logger-dispatch
  "Reactive dispatch overlay for logger."

    #'debug-print-message

    :halt
    #'do-before-halt}))

(defn find-last-catchup-id
  "Find the ID of the last message we'd caught up to, or nil."
  [logfile]
  (with-open [rdr (io/reader logfile :encoding "UTF-8")]
    (->> (json/parsed-seq rdr true)
         (filter #(= (:hl-type %) "caughtup"))
         (last)
         (:data)
         (:id))))

(defn -main
  "Demo connection to heim"
  [server room logfile]
  (let [w (io/writer logfile :encoding "UTF-8" :append true)
        session (run server room
                     {:logger
                      {:lifecycle :catchup
                       ;; Last message ID from last session,
                       ;; used for backlog catchup
                       :catchup-to-id (find-last-catchup-id logfile)
                       ;; Last message from this session, used
                       ;; to mark place for next session's
                       ;; catchup.
                       :last-seen-msg nil
                       :path logfile
                       :writer w}}
                     logger-dispatch)]
    session))
