 (ns lcmap.aardvark.landsat
   "Resources and representations.
 
-  This namespace contains all route definitions."
+  This namespace contains all route definitions and functions
+  transforming/validating requests. Other namespaces handle
+  implementation details related to persistence and messaging."
   (:require [camel-snake-kebab.core :refer [->snake_case_keyword]]
             [camel-snake-kebab.extras :refer [transform-keys]]
             [cheshire.core :as json]

(defn put-source
  "Handle request for creating a source and produce a response."
  [source-id {params :params :as req}]
  (let [source (merge {:id source-id :progress_name "created"} params)]
    (or (some->> (source/validate source)
                 (assoc {:status 403} :body))

;;; Response entity transformers.

(defn to-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
  "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))

