 
 (comment
 
+  (do
   (def test1
-    [{:a "A" :b "B" :c "C"}
-     {:a "D" :c "D"}
-     {:a "A" :d "D"}])
+    [{:a "A1" :b "B1" :c "C1"}
+     {:a "A2" :c "C2"}
+     {:a "A1" :d "D1"}])
+
+  (def test2
+    [{:a "A1" :b "B1"}])
+
+  (def test3
+    [{:a "A1" :c "C1"}]) )
 
   (get-subfields-for-keyword [:b :c :d] test1 :a "A")
+  {:a (parse-hierarchical-keywords [:a :b :c :d] test1)}
+
+  {:a [{:value "A1"
+        :subfields ["b" "d"]
+        :b [{:value "B1"
+             :subfields ["c"]
+             :c [{:value "C1"}]}]
+        :d [{:value "D1"}]}
+       {:value "A2"
+        :subfields ["c"]
+        :c [{:value "C2"}]}]}
+
+  (get-subfields-for-keyword [:b :c :d] test1 :a "A1")
+  (get-subfields-for-keyword [:b :c :d] test1 :a "A2")
+
+  {:a (parse-hierarchical-keywords [:a :b :c :d] test1)}
+
+  (= {:a (parse-hierarchical-keywords [:a :b :c :d] test1)}
+     {:a [{:value "A1"
+        :subfields ["b" "d"]
+        :b [{:value "B1"
+             :subfields ["c"]
+             :c [{:value "C1"}]}]
+        :d [{:value "D1"}]}
+       {:value "A2"
+        :subfields ["c"]
+        :c [{:value "C2"}]}]})
 
   )
 (defn- get-subfields-for-keyword
   "Figure out which subfield is directly below the current keyword. It is possible the next field
-  field in the hierarchy is nil, but further down the chain there is a non-nil field."
+  in the hierarchy is nil, but further down the chain there is a non-nil field."
   [remaining-hierarchy keywords field value]
   (loop [remaining-fields remaining-hierarchy
          matching-keywords (filter #(= value (field %)) keywords)
          all-subfields nil]
           (let [next-field (first remaining-fields)
-                keywords-below-with-next-field (keep next-field matching-keywords)
+                keywords-below-with-next-field (when next-field (keep next-field matching-keywords))
                 keywords-with-nil-next-field (filter #(nil? (next-field %)) matching-keywords)
                 all-subfields (if (seq keywords-below-with-next-field)
                                 (conj all-subfields next-field)

                                :variable-level-1 [{:value "MOBILE GEOGRAPHIC INFORMATION SYSTEMS"
                                                    :uuid "0dd83b2a-e83f-4a0c-a1ff-2fbdbbcce62d"
                                                    }]}]}]}]}

  (def keyword-hierarchy
    {:science-keywords [:category :topic :term :variable-level-1 :variable-level-2 :variable-level-3]
     :providers [:level-0 :level-1 :level-2 :level-3 :short-name :long-name]
     :platforms [:category :series-entity :short-name :long-name]
     :instruments [:category :class :type :subtype :short-name :long-name]})

  (def keywords
    [{:uuid "0dd83b2a-e83f-4a0c-a1ff-2fbdbbcce62d",

                (recur (rest remaining-fields) keywords-with-nil-next-field all-subfields)
                all-subfields))))

(comment
  (get-hierarchy-after (:providers the-keyword-hierarchy) :level-1))

(def keyword-hierarchy
  {:science-keywords [:category :topic :term :variable-level-1 :variable-level-2 :variable-level-3]
   :providers [:level-0 :level-1 :level-2 :level-3 :short-name :long-name]
   :platforms [:category :series-entity :short-name :long-name]
   :instruments [:category :class :type :subtype :short-name :long-name]})

(defn- get-hierarchy-from-field
  "Returns all of the fields in the hierarchy starting from the provided field and including all
  fields after."
  [keyword-hierarchy field]
  (let [field-index (.indexOf keyword-hierarchy field)]
    (filter #(<= field-index (.indexOf keyword-hierarchy %)) keyword-hierarchy)))

(defn- parse-hierarchical-keywords
  "Returns keywords in a hierarchical fashion based on the provided keyword hierarchy and keywords."
  [keyword-hierarchy keywords]
  (when-let [field (first keyword-hierarchy)]
    (let [next-field (second keyword-hierarchy)
          unique-values (distinct (keep field keywords))
          values-to-uuids (into {} (keep (fn [k-word]
                                           (when (is-leaf? (rest keyword-hierarchy) k-word)
                                             [(field k-word) (:uuid k-word)]))
                                         keywords))]
      (for [value unique-values
            :let [all-subfield-names (get-subfields-for-keyword (rest keyword-hierarchy) keywords
                                                                field value)
                  uuid (get values-to-uuids value)
                  value-map (util/remove-nil-keys
                              {:value value
                               :uuid uuid})
                  subfield-maps (util/remove-nil-keys
                                  (into {}
                                        (for [subfield-name all-subfield-names
                                              :let [subfields
                                                    (parse-hierarchical-keywords
                                                      (get-hierarchy-from-field keyword-hierarchy subfield-name)
                                                      (filter #(= value (field %)) keywords))]]
                                          [subfield-name (seq subfields)])))]]
        ; (reduce #(assoc value-map (:subfield-name %) (:subfields %))
        (util/remove-nil-keys
          (merge value-map subfield-maps {:subfields (seq (map name (keys subfield-maps)))}))))))

        ; (if (seq subfields)
        ;   (assoc value-map
        ;          :subfields [(name next-field)]
        ;          next-field subfields)
        ;   value-map))))))

; (defn- parse-hierarchical-keywords
;   "Returns keywords in a hierarchical fashion based on the provided keyword hierarchy and keywords."
;   [keyword-hierarchy keywords]
;   (when-let [field (first keyword-hierarchy)]
;     (let [next-field (second keyword-hierarchy)

;           ;; Find distinct values
;           unique-values (distinct (keep field keywords))
;           values-to-uuids (into {} (keep (fn [k-word]
;                                            (when (is-leaf? (rest keyword-hierarchy) k-word)
;                                              [(field k-word) (:uuid k-word)]))
;                                          keywords))]
;       (for [value unique-values
;             :let [subfields (parse-hierarchical-keywords
;                               (rest keyword-hierarchy)
;                               (filter #(= value (field %)) keywords))
;                   uuid (get values-to-uuids value)
;                   value-map (util/remove-nil-keys
;                               {:value value
;                                :uuid uuid})]]

;         (if (seq subfields)
;           (assoc value-map
;                  :subfields [(name next-field)]
;                  next-field subfields)
;           value-map)))))

(def keyword-api-routes
  (context "/keywords" []
