(ns wanijo.handler
  (:require [clojure.string :refer [starts-with?]]
            [compojure.core
             :refer [defroutes routes context]]
            [compojure.route :as route]
            [ring.middleware.defaults
             :refer [wrap-defaults site-defaults]]
            [ring.util.response :as rur]
            [ring.middleware.session.cookie :as session-cookie]
            [ring.middleware.json :as ring-json]
            [clojure.spec.alpha :as spec]
            [wanijo.home.routes :as home-routes]
            [wanijo.schema
             [routes :as schema-routes]
             [middleware :as schema-middleware]]
            [wanijo.user.routes :as user-routes]
            [wanijo.attribute.routes :as attr-routes]
            [wanijo.instance.routes :as instance-routes]
            [wanijo.visualisation.routes :as vis-routes]
            [wanijo.tag.routes :as tag-routes]
            [wanijo.infrastructure
             [auth :as auth]
             [devmode :as devmode]
             [routing :refer [path]]]
            [wanijo.public.routes :as public-routes]))

(defn- wrap-login-redirect [handler]
  (fn [req]
    (if (or (get-in req [:session :ident])
            (starts-with? (:uri req) "/public"))
      (handler req)
      (rur/redirect (path :public-index)))))

(defroutes app-routes
  (routes auth/routes
          public-routes/routes)
  (wrap-login-redirect
    (routes home-routes/routes
            schema-routes/routes
            user-routes/routes
            attr-routes/routes
            instance-routes/routes
            vis-routes/routes
            tag-routes/routes))
  (route/not-found "Not Found"))

(def standalone-app
  (-> app-routes
      schema-middleware/wrap-user-schemas!
      ring-json/wrap-json-response
      (wrap-defaults site-defaults)))

(defn wrap-spec-asserts [handler]
  (fn [req]
    (spec/check-asserts true)
    (handler req)))

(def dev-app
  (-> app-routes
      wrap-spec-asserts
      devmode/wrap-devmode
      schema-middleware/wrap-user-schemas!
      ring-json/wrap-json-response
      (wrap-defaults
        (assoc-in site-defaults
                  [:session :store]
                  (session-cookie/cookie-store
                    {:key "1234567890123456"})))))
