#lang imperative-syndicate

(require/activate imperative-syndicate/broker)
(require/activate imperative-syndicate/drivers/external-event)
(require (only-in racket/port read-line-evt))

(assertion-struct Present (name))
(message-struct Says (who what))

(spawn #:name 'main
       (field [username (symbol->string (strong-gensym 'chatter-))])

       (define root-facet (current-facet))
       (define url standard-localhost-broker/tcp)
       (during (broker-connected url)
         (on-start (log-info "Connected to broker."))
         (on-stop (log-info "Disconnected from broker."))

         (on (asserted (from-broker url (Present $who))) (printf "~a arrived.\n" who))
         (on (retracted (from-broker url (Present $who))) (printf "~a departed.\n" who))
         (on (message (from-broker url (Says $who $what))) (printf "~a: ~a\n" who what))

         (assert (to-broker url (Present (username))))

         (define stdin-evt (read-line-evt (current-input-port) 'any))
         (on (message (inbound (external-event stdin-evt (list $line))))
             (match line
               [(? eof-object?) (stop-facet root-facet)]
               [(pregexp #px"^/nick (.+)$" (list _ newnick)) (username newnick)]
               [other (send! (to-broker url (Says (username) other)))]))))
