instaweb.ss
(module instaweb mzscheme
  
  (require (lib "kw.ss")
           (lib "pretty.ss")
           (lib "runtime-path.ss")
           (lib "sendurl.ss" "net")
           (lib "cut.ss" "srfi" "26"))
  
  (require (planet "instaweb.ss" ("schematics" "instaweb.plt" 2 1)))
  
  (require (file "base.ss")
           (file "instaweb-servlet-config.ss"))
  
  ; Variables ------------------------------------
  
  ;; htdocs-path : path
  ;; delirium-servlet-path : path
  ;; delirium-servlet-config-path : path
  (define-runtime-path htdocs-path "htdocs")
  (define-runtime-path delirium-servlet-path "instaweb-servlet.ss")
  (define-runtime-path delirium-servlet-config-path "instaweb-servlet-config.ss")
  
  ; Procedures -----------------------------------
  
  (define undefined-keyword
    (gensym))
  
  ;; instaweb/delirium : #:port            integer
  ;;                     #:test            schemeunit-test
  ;;                    [#:run-tests       (-> schemeunit-test any)]
  ;;                    [#:servlet-path    (U path string)]
  ;;                    [htdocs-path       (list-of (U path string))]
  ;;                    [servlet-namespace (list-of require-spec)]
  ;;                 -> void
  (define instaweb/delirium 
    (let* ([undefined (gensym 'undefined)]
           [defined?  (lambda (val) 
                        (not (eq? val undefined)))])
      (lambda/kw (#:key
                  port
                  test 
                  [listen-ip                                    "127.0.0.1"]
                  [run-tests                                    test/text-ui/pause-on-fail]
                  [target-servlet-path      #:servlet-path      "servlet.ss"]
                  [target-htdocs-path       #:htdocs-path       undefined]
                  [target-servlet-namespace #:servlet-namespace undefined]
                  [run-tests?                                   #t]
                  [send-url?                                    #t]
                  [test-url                                     undefined]
                  [new-window?                                  #t]
                  #:other-keys+body other)
        (let* ([dispatcher-plist
                (if run-tests?
                    (begin (set-target-servlet-path! target-servlet-path)
                           (set-target-test! test)
                           (set-test-runner! run-tests)
                           `(#:servlet-path
                             ,delirium-servlet-path
                             #:htdocs-path
                             ,(cons htdocs-path 
                                    (if (defined? target-htdocs-path)
                                        target-htdocs-path
                                        null))
                             #:servlet-namespace
                             ,(cons `(file ,(path->string delirium-servlet-config-path))
                                    (if (defined? target-servlet-namespace)
                                        target-servlet-namespace
                                        null))
                             ,@other))
                    (begin `(#:servlet-path
                             ,target-servlet-path
                             ,@(if (defined? target-htdocs-path)
                                   `(#:htdocs-path ,target-htdocs-path)
                                   null)
                             ,@(if (defined? target-servlet-namespace)
                                   `(#:servlet-namespace ,target-servlet-namespace)
                                   null)
                             ,@other)))]
               [test-url*
                (if (defined? test-url)
                    test-url
                    (format "http://localhost:~a/test" port))]
               [run-delirium/instaweb-server
                (cut run-server port listen-ip dispatcher-plist)])
          (if run-tests?
              (begin (when send-url?
                       (send-url test-url* new-window?))
                     (console-loop run-delirium/instaweb-server))
              (begin (apply instaweb #:port port #:listen-ip listen-ip dispatcher-plist)))))))
  
  ; Provide statements ---------------------------
  
  (provide instaweb/delirium
           test/text-ui/pause-on-fail)
  
  )