       else if status.rowCount == 0
         msg.send "Gerrit didn't find anything matching your query"
       else
-        msg.send formatQueryResult r for r in results when r.id
+        msg.send formatters.queryResult change: r for r in results when r.id
 
 ignoreOrReportEventsMe = (robot, gerrit) -> (msg) ->
   type = msg.match[2].toLowerCase()


  isIgnored = (type, thing) -> (t for t in ignoresOfType robot, type when t is thing).length != 0
  isWanted = (event) -> !(
    isIgnored("project", extractProject event) ||
    isIgnored("user", extractName event) ||
    isIgnored("event", event.type))

  streamEvents.stderr.on "data", (data) ->
    robot.logger.info "Gerrit stream-events: #{data}"
  streamEvents.stdout.on "data", (data) ->
    json = JSON.parse data
    msg = formatEvent json
    if msg == null
      robot.logger.info "Gerrit stream-events: Unrecognized event #{data}"
    else if msg && isWanted json
      # Bug in messageRoom? Doesn't work with multiple rooms

#   To disable event stream spam, use the value "disabled"
eventStreamRooms = process.env.HUBOT_GERRIT_EVENTSTREAM_ROOMS

# TODO: Make these template driven with env-var overrides possible.
# See the following for descriptions of the input JSON data:
# http://gerrit-documentation.googlecode.com/svn/Documentation/2.4/json.html
# http://gerrit-documentation.googlecode.com/svn/Documentation/2.4/cmd-stream-events.html
formatters =
  queryResult:          (json) -> "'#{json.change.subject}' for #{json.change.project}/#{json.change.branch} by #{extractName json.change} on #{formatDate json.change.lastUpdated}: #{json.change.url}"
  events:
    "patchset-created": (json) -> "#{extractName json} uploaded patchset #{json.patchSet.number} of '#{json.change.subject}' for #{json.change.project}/#{json.change.branch}: #{json.change.url}"
    "change-abandoned": (json) -> "#{extractName json} abandoned '#{json.change.subject}' for #{json.change.project}/#{json.change.branch}: #{json.change.url}"
    "change-restored":  (json) -> "#{extractName json} restored '#{json.change.subject}' for #{json.change.project}/#{json.change.branch}: #{json.change.url}"
    "change-merged":    (json) -> "#{extractName json} merged patchset #{json.patchSet.number} of '#{json.change.subject}' for #{json.change.project}/#{json.change.branch}: #{json.change.url}"
    "comment-added":    (json) -> "#{extractName json} reviewed patchset #{json.patchSet.number} (#{extractReviews json}) of '#{json.change.subject}' for #{json.change.project}/#{json.change.branch}: #{json.change.url}"
    "ref-updated":      (json) -> "#{extractName json} updated reference #{json.refUpdate.project}/#{json.refUpdate.refName}"

formatDate = (seconds) -> new Date(seconds * 1000).toDateString()
extractName = (json) ->
  account = json.uploader || json.abandoner || json.restorer || json.submitter || json.author || json.owner
  account?.name || account?.email || "Gerrit"
extractReviews = (json) ->
  ("#{a.description}=#{a.value}" for a in json.approvals).join ","

module.exports = (robot) ->
  gerrit = url.parse sshUrl
