   (:require [clojure.stacktrace :as strace])
   (:gen-class))
 
-;;;; Resilient message decoding
-
-;; Single fragment decoding -- trivial case
-;;  * forward to processing pipeline
-
-;; Multi fragment decoding -- nontrivial
-;;
-;; Multiple cases -- each depending on sequencing order
-;;
-;; 1. A - B
-;;  * messages stream back-to-back in correct ordinal positions
-;;
-;; 2. B - A
-;;  * messages stream back-to-back in reversed ordinal positions
-;;
-;; 3. A - X+ - B
-;;  * messages stream in correct ordinal positions separated by + messages
-;;
-;; 4. B - X+ - A
-;;  * messages stream in reversed ordinal positions separated by + messages
-;;
-;;
-
-(def buffer-size 1000)
+;;;                      ____                     _           
+;;;                     |  _ \  ___  ___ ___   __| | ___ _ __ 
+;;;                     | | | |/ _ \/ __/ _ \ / _` |/ _ \ '__|
+;;;                     | |_| |  __/ (_| (_) | (_| |  __/ |   
+;;;                     |____/ \___|\___\___/ \__,_|\___|_|   
+;;;
+;;; The following application is a robust implemenation of ais-lib's core decoding functionality.  In practice, multipart 
+;;; messages tend to stream in correct monotonically increasing order however we must account for all streaming configurations
+;;; and not naively consume input streams.
+;;; 
+;;; Consider two sets or multipart messages, [a, a'] and [b, b']. x+ denotes 1 more messages.
+;;;
+;;; We must consider the following senarios when parsing multipart fragments from input streams:
+;;;
+;;; 1. a  a'
+;;; 2. a' a
+;;; 3. a  x+ a'
+;;; 4. a' x+ a
+;;; 5. a  b' b a'
+;;;
+;;;
+;;; Entry point parameters:
+;;;  * output-prefix: string
+;;;    - Output filename prefix
+;;;  * supported-types: [1-28]
+;;;    - Messages types to decode.  All other messages are dropped
+;;;  * n-threads: [1..)
+;;;    - Number of processing threads.  Also sets the number of output files (where output files have the suffix
+;;;      part-n).
+;;;  * format: [csv | json]
+;;;    - Output file data format
+;;;
+
+
+(def buffer-size 1000) 
 
 (def ais-msg-types (into {} (for [k (range 1 28)] [k false])))
 

;; Core
;;---


(defn details [line]
  (hash-map
    "line"       line
    "frag-count" (ais-ex/parse "frag-count" line)
    "frag-num"   (ais-ex/parse "frag-num" line)
    "type"       (extract-type (ais-ex/parse "payload" line))))

        (if-let [line (async/<!! in-ch)]
          (do 
            (when (valid-syntax? line)
              (let [d (details line)]
                (if (passthru? supported-types d)
	          (condp = (d "frag-count")
	            1 (async/>!! out-ch [line])
	            2 (consume-multipart line (async/<!! in-ch) unpaired-frags out-ch)
	     	    (.println *err* (str "Unexpected fragment count: " (d "frag-count") ". " line))) 
	          (.println *err* (str "Dropping [type=" (d "type") "] " line))))) 
            (recur))
          (async/close! out-ch))))
    out-ch))
