   ([key-path] (com/get-db app-db key-path)))
 
 
-;;; ------------------------------------------------------------------------;;;
-;;;                      Server routes and handlers                         ;;;
-;;; ------------------------------------------------------------------------;;;
-
-
-(defn landing-handler [request]
-  #_(infof "landing handler request: %s" request)
+
+
+;;; ------------------------------------------------------------------------;;;
+;;;                   Aerobio Application Messaging...                      ;;;
+;;; ------------------------------------------------------------------------;;;
+
+(defmulti user-msg :op)
+
+(defmethod user-msg :default [msg]
+  (infof "ERROR: unknown user message %s" msg)
+  #_(srv/send-msg
+   (msg :ws) {:op "error" :payload "ERROR: unknown user message"}))
+
+
+
+
+;;; ------------------------------------------------------------------------;;;
+;;;                Control  starting and stoping Webserver                  ;;;
+;;; ------------------------------------------------------------------------;;;
+
+(defn msg-handler [msg]
+  (infof ":MSG-HANDLER :MSG %s" msg)
+  (let [{:keys [op data]} (msg :data)]
+    (case op
+      ;;null for now
+      (user-msg (msg :data)))))
+
+
+(defn on-open [ch op payload]
+  (let [ws payload
+        uid-name ((-> :idfn get-adb first))
+        connfn (-> :connfn get-adb first)
+        uuid (uuid)
+        uid {:uuid uuid :name uid-name}
+        data (connfn {:uid uid})
+        name-uuids (or (get-adb uid-name) [])]
+    (infof ":SRV :open %s" uid)
+    (update-adb [uuid :ws] ws, [uuid :name] uid-name
+                [uuid :rcvcnt] 0, [uuid :sntcnt] 0
+                [ws :uuid] uuid
+                uid-name (conj name-uuids uuid))
+    (srv/send-msg ws {:op :register :data data})))
+
+
+(defn server-dispatch [ch op payload]
+  (case op
+    :msg (let [{:keys [ws]} payload]
+           (msg-handler payload)
+           (update-adb :rcvcnt inc, [ws :rcvcnt] inc))
+
+    :open (on-open ch op payload)
+    :close (let [{:keys [ws status]} payload
+                 uuid (get-adb [ws :uuid])
+                 uuid-name (get-adb [uuid :name])
+                 uuids (get-adb uuid-name)]
+             (infof ":SRV :close :uuid %s, :uuid-name %s" uuid uuid-name)
+             (update-adb ws :rm, uuid :rm
+                         uuid-name (->> uuids (remove #(= uuid %)) vec)))
+
+    :bpwait (let [{:keys [ws msg encode]} payload
+                  uuid (get-adb [ws :uuid])]
+              (infof ":SRV :uuid %s - Waiting to send msg %s" uuid msg)
+              (update-adb [uuid :bpdata] {:msg msg, :encode encode}))
+    :bpresume (let [{:keys [ws msg]} payload
+                    uuid (get-adb [ws :uuid])
+                    encode ((get-adb [uuid :bpdata]) :encode)]
+                (infof ":SRV BP Resume :uuid %s" (get-adb [ws :uuid]))
+                (srv/send-msg ws msg :encode encode))
+
+    :sent (let [{:keys [ws msg]} payload]
+            #_(infof ":SRV Sent msg %s" msg)
+            (update-adb :sntcnt inc, [ws :sntcnt] 0))
+    :failsnd (infof ":SRV Failed send for {:op %s :payload %s}" op payload)
+
+    :stop (let [{:keys [cause]} payload]
+            (infof ":SRV Stopping reads... Cause %s" cause)
+            (update-adb)
+            (srv/stop-server))
+    (infof ":SRV :WTF {:op %s :payload %s}" op payload)))
+
+
+
+
+;;; ------------------------------------------------------------------------;;;
+;;;                Server routes, handlers, start and stop                  ;;;
+;;; ------------------------------------------------------------------------;;;
+
+
+(defn landing-handler [request index-path]
+  #_(printchan request)
   (content-type
    {:status 200
-    :body (io/input-stream (io/resource "public/index.html"))}
+    :body (io/input-stream (io/resource index-path))}
    "text/html"))
 
-
-(defn upload-file [args reqmap]
-  (println :ARGS args)
-  (println :REQMAP reqmap)
-  (let [resource-dir "/NextSeq/TVOLab"
-        base (fs/join "/data1" resource-dir)
-        files (->> args :dir (fs/join base)
-                   ((fn[d] (fs/directory-files d "")))
-                   (filter (fn[f] (not (fs/directory? f))))
-                   (map fs/basename))]
-    (hiccup/html
-     [:h1 "UPLD-file path"]
-     [:hr]
-     [:p (str "ARGS" args)]
-     [:hr]
-     [:p (str "REQMAP" reqmap)]
-     [:hr]
-     [:ul
-      (map #(vector :li [:a {:href (fs/join resource-dir (args :dir) %)} %])
-           files)])))
+(defn aerobio-routes [& {:keys [landing-handler index-path]
+                         :or {landing-handler landing-handler
+                              index-path "public/index.html"}}]
+  (apply routes
+         (conj (srv/hanasu-handlers)
+               (GET "/" request (landing-handler request index-path))
+               (route/resources "/"))))
+
+(defn aerobio-handler [aerobio-routes & middle-ware-stack]
+  (reduce (fn[R mwfn] (mwfn R)) aerobio-routes middle-ware-stack))
+
+
+
+(defn start-server
+  [port & {:keys [route-handler connfn]
+           :or {route-handler (aerobio-handler (aerobio-routes))
+                connfn identity}}]
+  (let [ch (srv/start-server port :main-handler route-handler)]
+    (printchan "Server start, reading msgs from " ch)
+    (update-adb :chan ch
+                :connfn [connfn])
+    (go-loop [msg (<! ch)]
+      (let [{:keys [op payload]} msg]
+        (future (server-dispatch ch op payload))
+        (when (not= op :stop)
+          (recur (<! ch)))))))
+
+(defn stop-server []
+  (async/>!! (get-adb :chan) {:op :stop :payload {:cause :userstop}}))
+
+
+#_(hmi/start-server
+   7070
+   :route-handler (hmi/aerobio-handler
+                   (hmi/aerobio-routes :index-path "public/Fig/index.html"))
+   :idfn (constantly "Exploring")
+   :connfn connfn)
+
 
 
 (def dbg (atom {}))

   [com.rpl.specter :as sp]

   [aerial.hanasu.server :as srv]
   [aerial.hanasu.common :as com]

   [aerial.fs :as fs]
   [aerial.utils.misc :as aum]

   [clojure.data.json :as json]
   [clojure.java.io :as io]
   [clojure.tools.reader.edn :as edn]
   [clojure.core.async :as async :refer (<! >! go go-loop)]

   [ring.middleware.defaults]
   [ring.middleware.gzip :refer [wrap-gzip]]
