#!/usr/bin/env node
var nopt    = require('nopt')
  , chalk   = require('chalk')
  , url     = require('url')
  , PouchDB = require('pouchdb')
  , Spinner = require('cli-spinner').Spinner
  , digest  = require('../lib')
  , mapKeys = require('lodash/object/mapKeys')
  , merge   = require('../lib/merge')

PouchDB.plugin(require('pouchdb-migrate'))

var manifest = require('../package.json')
  , knownOptions = { 'help' : Boolean
                   , 'version' : Boolean
                   , 'allow-duplicates' : Boolean
                   , 'debug' : Boolean
                   }
  , shortHands   = { 'h' : ['--help']
                   , 'v' : ['--version']
                   , 'A' : ['--allow-duplicates']
                   }
  , options      = nopt(knownOptions, shortHands)

function printVersion () {
  console.log(manifest.version)
}

function showHelp () {
  var name = Object.keys(manifest.bin)[0]
  console.log('Usage:', name, '[options]', '<database>')
  console.log('')
  console.log('Options:')
  console.log('  -v, --version             print version')
  console.log('  -h, --help                show help message')
  console.log('  -A, --allow-duplicates    do not aggregate duplicates')
  console.log('  --debug                   print debug info')
  console.log('')
  console.log('Examples:')
  console.log(' ', name, 'http://localhost:5984/persons')
  console.log(' ', name, '-A', 'https://user:pw@some.db.net/persons')
}

function abort (message) {
  console.error(chalk.red('Error:', message))
  process.exit(1)
}

function parseUrl (arg) {
  if (!arg) {
    abort('Missing required argument <database>')
  }

  arg = url.parse(arg)
  if (!arg.host) {
    abort('Invalid argument given')
  }
  return arg.href
}

if (options.version) {
  printVersion()
  process.exit()
}

if (options.help) {
  showHelp()
  process.exit()
}

options.database = parseUrl(options.argv.remain[0])
if (options.database) {
  var database   = new PouchDB(options.database)
    , spinner    = new Spinner(chalk.blue('%s Migrating database...'))
    , aggregator = (options.allowDuplicates) ? null : Object.create(null)

  spinner.start()
  database
    .migrate(function (doc) {
      return digest(doc, aggregator)
    })
    .then(function (result) {
      if (aggregator) {
        var rels = mapKeys( aggregator
                            , function (rel, key) { return rel[0]._id }
                            )
        return database.migrate(function (doc) {
          return merge(doc, rels)
        })
      }
    })
    .then(function () {
      spinner.stop(true)
      process.exit()
    })
    .catch(function (error) {
      spinner.stop(true)
      abort(error)
    })
}

@@ -2016,26 +2016,28 @@
 '%25s 
-Mig
+Ext
 ra
+c
 ting d
-atabase
+ocuments
 ...'
@@ -2070,15 +2070,17 @@
 ions
-.
+%5B'
 allow
-D
+-d
 upli
@@ -2084,16 +2084,18 @@
 plicates
+'%5D
 ) ? null
@@ -2245,14 +2245,17 @@
 on (
-result
+migration
 ) %7B%0A
@@ -2419,16 +2419,137 @@
       )%0A
+        spinner.stop(true)%0A        spinner = new Spinner(chalk.blue('%25s Merging duplicates...'))%0A        spinner.start()%0A
         
@@ -2641,32 +2641,32 @@
 %0A      %7D%0A    %7D)%0A
-
     .then(functi
@@ -2665,24 +2665,33 @@
 n(function (
+migration
 ) %7B%0A      sp

Improve spinner