 (def auth-backend
   (auth/session-backend))
 
+;; Define the application routes using `ct/routes`
+;; function from catacumba.
+
 (def app
-  (ct/routes [[:any (hs/session {:storage :inmemory})]
-              [:any (hs/auth auth-backend)
-              [:get home-page]
-              [:by-method "login"
-               [:get login-page]
-               [:post login-submit]]
-              [:prefix "assets"
-               [:assets "resources/public"]]]))
+  (ct/routes [[:prefix "assets"
+               [:assets "resources/public"]]
+              [:scope
+               [:any (hs/session {:storage :inmemory})]
+               [:any (hs/auth auth-backend)]
+               [:get home-page]
+               [:get "logout" logout-page]
+               [:by-method "login"
+                [:get login-page]
+                [:post login-submit]]]]))
 
-;; Start the server using the `run-server` function.
-;; This has one peculiarity, the `:registry` property. It
-;; is used for setup contextual objects and in this case
-;; the function `session-decorator` returns a handler
-;; decorator that it should be attached to the registry
+;; Define the main entry point that starts the catacumba
+;; server un the port 5051.
 
 (defn -main
   "The main entry point to your application."

;; Home Page
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Shows a simple html with two links, one to restricted area and
;; an other directly to the login. If you are go directly to the
;; restricted area without to be authenticated, you will be redirected
;; to the login page.

(defn home-page
  [context]
  (-> (layout [:section {:class "home-page"}
               [:p "Welcome to the dummy website application."]
               [:p [:a {:href "/restricted"} "Restricted Area"]]
               [:p [:a {:href "/login"} "Login"]]])
      (http/ok {:content-type "text/html"})))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Login page
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


(defn- render-login-page
  ([] (render-login-page []))

        username (get form-params "username" "")
        password (get form-params "password" "")]
    (if (or (empty? username) (empty? password))
      ;; Firstly validates the input, if required fields
      ;; are empty, render the login page html with
      ;; convenient error mesasage and return it.
      (http/ok (render-login-page ["The two fields are mandatory."])
               {:content-type "text/html"})

      ;; In case contrary, try validate the incoming
      ;; credentials, and in case of them validates
      ;; successful, update the session `:identity` key
      ;; with the authenticated user object.
      ;; In case contrary, return a login page
      ;; rendered with approapiate error message
      (if-let [user (authenticate username password)]
        (let [nexturl (get query-params "next" "/")
              session (:session context)]
          (swap! session assoc :identity user)
          (http/found nexturl))
        (http/ok (render-login-page ["User or password are incorrect"])
                 {:content-type "text/html"})))))
