(ns auto-ap.routes.graphql
  (:require
   [auto-ap.datomic :refer [conn pull-many]]
   [auto-ap.datomic.clients :as d-clients]
   [auto-ap.graphql :as ql]
   [auto-ap.graphql.utils :refer [limited-clients]]
   [auto-ap.logging  :as alog]
   [auto-ap.routes.utils :refer [wrap-secure]]
   [buddy.auth :refer [throw-unauthorized]]
   [clojure.edn :as edn]
   [clojure.set :as set]
   [datomic.api :as dc]))




(defn handle-graphql [{:keys [request-method query-params clients] :as r}]
  (when (= "none" (:user/role (:identity r)))
    (throw-unauthorized))

  (try
    (let [variables (some-> (query-params "variables")
                            edn/read-string)
          body (some-> r :body slurp)]
      
      {:status 200
       :body (pr-str (ql/query (:identity r) (if (= request-method :get) (query-params "query") body) (assoc variables
                                                                                                             :clients
                                                                                                             clients) ))
       :headers {"Content-Type" "application/edn"}})
    (catch Throwable e
      
      (if-let [result (:result (ex-data e))]
        (do (alog/warn ::result-error  :error e)
          {:status 400
           :body (pr-str result)
           :headers {"Content-Type" "application/edn"}})
        (if-let [message (:validation-error (ex-data (.getCause e)) )]
          (do 
            (alog/warn ::graphql-validation-error
                       :message message
                       :error    e)
            {:status 400
             :body (pr-str {:errors [{:message message}]})
             :headers {"Content-Type" "application/edn"}})
          (do (alog/error ::error :error e)
              {:status 500
               :body (pr-str {:errors [{:message (str "Unhandled error:" (str e))}]})
               :headers {"Content-Type" "application/edn"}}))))))


(def routes {"api/" {#"graphql/?" :graphql}})
(def match->handler {:graphql (wrap-secure handle-graphql)})
