 (def order-coordinate :coordinate)
 (def order-queryname :queryname)
 
+(defn- make-ref-map
+  [hdr]
+  (->> hdr
+       sam-util/make-refs
+       (map :name)
+       (map-indexed (fn [i val] {val i}))
+       (into {})))
+
 ;; Coordinate sorter
 ;; -----------------
 
 (defn- replace-header [hdr vn so]
-  (conj hdr {:HD {:VN vn, :SO so}}))
+  (assoc hdr :HD {:VN vn, :SO so}))
 
 (defn- compare-key-pos [ref-map b1 b2]
   (if (= (:rname b1) (:rname b2))


(defn clean-split-merge-cache
  [name-fn sorted-name-fn count]
  (let [clean (fn [path]
                (let [f (file path)]
                  (when (.exists f)
                    (.delete f))))]
    (doseq [i (range count)]
      (clean (name-fn i))
      (clean (sorted-name-fn i)))))

  (format "%s/%s_%05d.sorted.cache" util/temp-dir prefix i))

(defn- find-head
  [keyfn l]
  (reduce (fn [e1 e2]
            (let [v (keyfn e1 e2)]
              (cond
                (or (zero? v)
                    (neg? v)) e1
                (pos? v) e2)))
          l))

(defn- head
  [blocks ref-map]
  (->> blocks
       (map-indexed vector)
       (filter (fn [[_ b]] (not (nil? b))))
       (find-head (fn [[idx1 b1] [idx2 b2]]
                    (compare-key-pos ref-map b1 b2)))))

(defn split-sam
  [rdr name-fn]
  (let [hdr (io/read-header rdr)]
    (doall
     (->> (io/read-blocks rdr)
          (partition-all chunk-size)
          (map-indexed vector)
          (map (fn [[i blks]]
                 (let [f (name-fn i)]
                   (with-open [wtr (bam/writer f)]
                     (io/write-header wtr hdr)
                     (io/write-refs wtr hdr)
                     (io/write-blocks wtr blks))
                   f)))))))

(defn merge-sam
  [wtr header name-fn n]
  (let [rdrs (map #(bam/reader (name-fn %) :ignore-index true) (range n))
        ref-map (make-ref-map header)]
    (io/write-header wtr header)
    (io/write-refs wtr header)
    (loop [blocks-list (map #(io/read-blocks % {:mode :coordinate}) rdrs)]
