(defpackage #:weekend.examples.kitchensink
  (:use #:cl)
  (:local-nicknames
   (#:wknd #:weekend)))

(in-package #:weekend.examples.kitchensink)

(defparameter +fname+ "([^/]+)"
  "Match any ole character except /")

(defclass file ()
  ((name
    :reader name
    :initarg :name
    :initform (wknd::slot-required 'file 'name)))
  (:documentation "Serves files in the weekend/examples dir.")
  (:metaclass wknd::endpoint)
  (:method . :get)
  (:route-parts "file" +fname+)
  (:extractors :name))

(defun file-in-examples-dir (name)
  (merge-pathnames
   name
   (asdf:system-relative-pathname 'weekend "examples/")))

(defmethod wknd::handle ((req file))
  (let ((file (file-in-examples-dir (name req))))
    (unless (uiop:file-exists-p file)
      (wknd::not-found req))
    (wknd:handle-static-file
     file
     (or (wknd:mime-type file) "text/plain"))))

(defvar *identified-persons* nil)

(defclass identify-form ()
  ()
  (:documentation "Page to serve an identify form")
  (:metaclass wknd::endpoint)
  (:method . :get)
  (:route-parts "identify")
  (:content-type . "text/html"))

(defmethod wknd::handle ((req identify-form))
  "<html>
<head></head>
<body>
<form method='POST' action='/identify'>
<input name='name' placeholder='name'/>
</form>
</body>
</html>")

(defclass hello ()
  ()
  (:documentation "A Page that just says hello to an identified user. Redirects users to
identify themselves if no name is known.")
  (:metaclass wknd:endpoint)
  (:method . :get)
  (:route-parts "hello")
  (:content-type . "text/html"))

(defmethod wknd:authenticate ((req hello))
  (or (plusp (length (wknd:get-cookie "name")))
      (wknd:endpoint-redirect 'identify-form)))

(defmethod wknd::handle ((req hello))
  (with-output-to-string (*standard-output*)
    (princ "<html><head></head><body>")
    (format t "<p>hello ~a</p>" (wknd:get-cookie "name"))
    (princ "</body></html>")))

(defclass identify ()
  ((name :reader name :initarg :name :type string))
  (:metaclass wknd::endpoint)
  (:method . :post)
  (:route-parts "identify")
  (:documentation "Endpoint for identifying oneself."))

(defmethod wknd::handle ((req identify))
  (wknd:set-cookie "name" :value (name req))
  (wknd:endpoint-redirect 'hello))

(defvar *server* (make-instance 'hunchentoot:easy-acceptor
                   :port 8888))

(hunchentoot:start *server*)