 (defn exponential-backoff [attempt]
   (* 1000 (min (js/Math.pow 2 attempt) 20)))
 
+(defn hook-repl-printing-output! [respond-msg]
+  (defmethod out-print :repl [_ args]
+    (glog/info logger (str "Printing" (pr-str args)))
+    (respond-to respond-msg
+                {:output true
+                 :stream :out
+                 :args (mapv #(if (string? %) % (gjson/serialize %)) args)}))
+  (defmethod err-print :repl [_ args]
+    (respond-to respond-msg
+                {:output true
+                 :stream :err
+                 :args (mapv #(if (string? %) % (gjson/serialize %)) args)}))
+  (setup-printing!))
+
 (defn ws-connect [& [websocket-url']]
-  ;; TODO take care of forwarding print output to the connection
   (let [websocket (goog.net.WebSocket.)
         url (str (make-url websocket-url'))]
     (patch-goog-base)

(defn ^:export session-name [] (get-state ::session-name))
(defn ^:export session-id [] (get-state ::session-id))

(defn response-for [{:keys [uuid websocket]} response-body]
  (cond->
        {:uuid uuid
         :session-name (session-name)
         :response response-body}
    (and (nil? websocket) (session-id))
    (assoc :session-id (session-id))))

(defn respond-to [{:keys [websocket http-url] :as old-msg} response-body]
  (let [response (response-for old-msg response-body)]

  (swap! reload-promise-chain #(.then % (fn [_] (Promise. f)))))

;; --------------------------------------------------------------
;; REPL print forwarding
;; --------------------------------------------------------------

(goog-define print-output "console,repl")

(defn print-receivers [outputs]
  (->> (string/split outputs #",")
       (map string/trim)
       (filter (complement string/blank?))
       (map keyword)
       distinct))

(defmulti out-print (fn [k args] k))
(defmethod out-print :console [_ args]
  (.apply (.-log js/console) js/console (garray/clone (to-array args))))

(defmulti err-print (fn [k args] k))
(defmethod err-print :console [_ args]
  (.apply (.-error js/console) js/console (garray/clone (to-array args))))

(defn setup-printing! []
  (let [printers (print-receivers print-output)]
    (set-print-fn! (fn [& args] (doseq [p printers] (out-print p args))))
    (set-print-err-fn! (fn [& args] (doseq [p printers] (err-print p args))))))

#_ (printing-receivers "console,repl")

;; --------------------------------------------------------------
;; Websocket REPL
;; --------------------------------------------------------------

