// @flow

const pull = require('pull-stream')
const { bootstrap, binaryToB64 } = require('../util')
const { printJSON } = require('../../../client/cli/util')

module.exports = {
  command: 'query <queryString>',
  builder: {
    color: {
      type: 'boolean',
      description: 'Explicitly enable (or disable, with --no-color) colorized output.\n',
      default: null,
      defaultDescription: 'Print in color if stdout is a tty, and monochrome if piped or pretty-printing is disabled.'
    },
    pretty: {
      type: 'boolean',
      description: 'Pretty print the output.\n',
      default: true,
      defaultDescription: 'True.  Use --no-pretty for compact output.'
    }
  },
  description: 'Query a remote peer using the mediachain peer-to-peer query protocol.\n',
  handler: (opts: {queryString: string, dir?: string, remotePeer?: string, identityPath: string, pretty: boolean, color?: boolean}) => {
    const {queryString, remotePeer, pretty, color} = opts
    if (remotePeer == null) {
      // TODO: better message
      console.error('remotePeer is required.')
      process.exit(1)
    }

    let node, remote
    bootstrap(opts).then(nodes => {
        node = nodes.node
        remote = nodes.remote
        return node.start()
      })
      .then(() => {
        if (remote == null) {
          throw new Error('Remote peer is unavailable')
        }

        return node.remoteQueryStream(remote.remotePeerInfo, queryString)
          .then(stream => printResultStream(stream, color, pretty))
      })
      .then(() => { process.exit(0) })
      .catch(err => {
        console.error(err.message)
        process.exit(1)
      })
  }
}

function printResultStream (queryStream: Function, color: ?boolean, pretty: boolean): Promise<void> {
  return new Promise((resolve, reject) => {
    pull(
      queryStream,
      pull.through(result => {
        printJSON(binaryToB64(result), {color, pretty})
      }),
      pull.onEnd((err) => {
        if (err) return reject(err)
        resolve()
      })
    )
  })
}


@@ -214,24 +214,217 @@
  builder: %7B%0A
+    withObjects: %7B%0A      type: 'boolean',%0A      alias: 'o',%0A      description: 'Also fetch the associated objects for each query result and display them inline.%5Cn',%0A      default: false%0A    %7D,%0A
     color: %7B
@@ -420,24 +420,24 @@
    color: %7B%0A
-
       type: 
@@ -1084,16 +1084,38 @@
  color?:
+ boolean, withObjects:
  boolean
@@ -1171,16 +1171,29 @@
 y, color
+, withObjects
 %7D = opts
@@ -1392,18 +1392,16 @@
 %7B%0A      
-  
 node = n
@@ -1410,18 +1410,16 @@
 es.node%0A
-  
       re
@@ -1440,26 +1440,24 @@
 emote%0A      
-  
 return node.
@@ -1464,18 +1464,16 @@
 start()%0A
-  
     %7D)%0A 
@@ -1592,30 +1592,201 @@
  %7D%0A%0A        
-return
+let queryPromise%0A        if (withObjects) %7B%0A          queryPromise = node.remoteQueryWithDataStream(remote.remotePeerInfo, queryString)%0A        %7D else %7B%0A          queryPromise =
  node.remote
@@ -1825,32 +1825,71 @@
 o, queryString)%0A
+        %7D%0A%0A        return queryPromise%0A
           .then(

add --withObjects flag to inline data objects with query results