 ;;; Response entity transformers.
 
 (defn to-html
-  "Encode response body as HTML."
+  "Transform response body into HTML."
   [response]
   (log/debug "responding with HTML")
   (let [template-fn (:template (meta response) html/default)]
     (update response :body template-fn)))
 
 (defn to-json
-  "Encode response body as JSON."
+  "Transform response body into JSON."
   [response]
   (log/debug "responding with json")
   (-> response
       (update :body json/encode)
       (assoc-in [:headers "Content-Type"] "application/json")))
 
+;; This is a list of supported types. By default a response will be
+;; produced as JSON, even if no accept media-ranges are provided.
+;; Even though this isn't technically correct, it's good-enough for
+;; the time being. It might be better to handle and empty accept header
+;; differently than an accept header that only request unsupported
+;; content-types.
+;;
+;; This uses a utility function provided by ring-accept instead
+;; of a macro so that debugging is somewhat easier.
 (def supported-types (accept :default to-json
                              "application/json" to-json
                              "text/html" to-html))
 
 (defn respond-with
-  ""
+  "Transform a data structure into a suitable representation."
   [request response]
   (supported-types request response))
 


(defn get-tiles
  "Get tiles containing point for given UBID and ISO8601 time range."
  [{{:keys [:ubid :x :y :acquired]} :params :as req}]
  (let [tile+    {:ubids (vectorize ubid)
                  :x (Integer/parseInt x)
                  :y (Integer/parseInt y)
                  :acquired (str/split acquired #"/")}
        tiles (tile/find tile+)]
    (log/debugf "GET /landsat/tiles")
    {:status 200 :body tiles}))

(defn get-tile-spec
  "Search for a source and produce a response map."
  [ubid {params :params :as req}]
  (if-let [results (first (tile-spec/query (merge {:ubid ubid} params)))]
    {:status 200 :body results}
    {:status 404 :body nil}))


;;; Response producing functions

(defn allow
  "Indicate allowed verbs."
  [& verbs]
  (log/debugf "explaining allow verbs")
  {:status 405
   :headers {"Allow" (str/join "," verbs)}})

(defn check-health
  "Indicate status of backing services."
  []
  (log/debugf "checking app health")
  (let [service-status (health/health-status)]
    (if (every? (fn [[_ {is :healthy}]] is) service-status)
      {:status 200 :body service-status}
      {:status 503 :body service-status})))

(defn sample-source
  "Retrieve some random sources."
  []
  (log/debugf "summarizing sources")
  {:status 200 :body (source/sample 10)})

(defn get-source
  "Search for source by ID."
  [source-id]
  (log/debugf "get source: %s" source-id)
  (if-let [result (seq (source/search source-id))]
    {:status 200 :body result}
    {:status 404 :body []}))
