(ns auto-ap.handler
  (:require [amazonica.core :refer [defcredential]]
            [auto-ap.routes.auth :as auth]
            [auto-ap.routes.companies :as companies]
            [auto-ap.routes.invoices :as invoices]
            [auto-ap.routes.reminders :as reminders]
            [auto-ap.routes.graphql :as graphql]
            [auto-ap.routes.vendors :as vendors]
            [auto-ap.routes.checks :as checks]
            [auto-ap.db.utils :as u]
            [buddy.auth.backends.token :refer [jws-backend]]
            [buddy.auth.middleware :refer [wrap-authentication
                                           wrap-authorization]]
            [clojure.java.jdbc :as jdbc]
            [compojure.core :refer :all]
            [compojure.route :as route]
            [config.core :refer [env]]
            [ring.middleware.edn :refer [wrap-edn-params]]
            [ring.middleware.multipart-params :as mp]
            [ring.middleware.params :refer [wrap-params]]
            [ring.middleware.reload :refer [wrap-reload]]
            [ring.util.response :as response]))

(defcredential (:aws-access-key-id env) (:aws-secret-access-key env) (:aws-region env))

(defroutes static-routes
  (GET "/"  [] (response/resource-response "index.html" {:root "public"})) 
  (route/resources "/")
  (routes (ANY "*" [] (response/resource-response "index.html" {:root "public"}))))

(defroutes api-routes
  (context "/api" []
           invoices/routes
           companies/routes
           vendors/routes
           reminders/routes
           checks/routes
           graphql/routes
           auth/routes))


(def auth-backend (jws-backend {:secret (:jwt-secret env) :options {:alg :hs512}}))

(def app-routes
  (routes 
   api-routes
   static-routes))

(defn wrap-transaction [handler]
  (fn [request]
    (jdbc/with-db-transaction [t (u/get-conn)]
      (binding [u/current-conn t]
        (try
          (handler (assoc request :db-conn t))
          (catch Exception e
            (jdbc/db-set-rollback-only! t)
            (throw e)))))))

(def app
  (->  #'app-routes
       (wrap-transaction)
      (wrap-authorization auth-backend)
      (wrap-authentication auth-backend)
      (wrap-reload)
      (wrap-params)
      (mp/wrap-multipart-params)
      (wrap-edn-params)))
