#!/usr/bin/env node

// Show logs
process.env.DEBUG = 'nuxt:*'

var _ = require('lodash')
var debug = require('debug')('nuxt:build')
debug.color = 2 // force green color
var fs = require('fs')
var parseArgs = require('minimist')
var Nuxt = require('../')
var chokidar = require('chokidar')
var resolve = require('path').resolve
var without = require('lodash').without

var argv = parseArgs(process.argv.slice(2), {
  alias: {
    h: 'help',
    H: 'hostname',
    p: 'port',
    c: 'config-file'
  },
  boolean: ['h'],
  string: ['H', 'c'],
  default: {
    c: 'nuxt.config.js'
  }
})

if (argv.hostname === '') {
  console.error(`> Provided hostname argument has no value`)
  process.exit(1)
}

if (argv.help) {
  console.log(`
    Description
      Starts the application in development mode (hot-code reloading, error
      reporting, etc)
    Usage
      $ nuxt dev <dir> -p <port number> -H <hostname>
    Options
      --port, -p          A port number on which to start the application
      --hostname, -H      Hostname on which to start the application
      --config-file, -c   Path to Nuxt.js config file (default: nuxt.config.js)
      --help, -h          Displays this message
  `)
  process.exit(0)
}

var rootDir = resolve(argv._[0] || '.')
var nuxtConfigFile = resolve(rootDir, argv['config-file'])

var options = {}
if (fs.existsSync(nuxtConfigFile)) {
  options = require(nuxtConfigFile)
} else if (argv['config-file'] !== 'nuxt.config.js') {
  console.error(`> Could not load config file ${argv['config-file']}`)
  process.exit(1)
}
if (typeof options.rootDir !== 'string') {
  options.rootDir = rootDir
}
// Force development mode: add hot reloading and watching changes
options.dev = true

var nuxt = new Nuxt(options)
var port = argv.port || process.env.PORT || process.env.npm_package_config_nuxt_port
var host = argv.hostname || process.env.HOST || process.env.npm_package_config_nuxt_host
var server = new Nuxt.Server(nuxt).listen(port, host)

listenOnConfigChanges(nuxt, server)

function listenOnConfigChanges(nuxt, server) {
  // Listen on nuxt.config.js changes
  var build = _.debounce(() => {
    debug('[nuxt.config.js] changed')
    delete require.cache[nuxtConfigFile]
    var options = {}
    if (fs.existsSync(nuxtConfigFile)) {
      try {
        options = require(nuxtConfigFile)
      } catch (e) {
        return console.error(e) // eslint-disable-line no-console
      }
    }
    options.rootDir = rootDir
    nuxt.close()
      .then(() => {
        debug('Rebuilding the app...')
        var nuxt = new Nuxt(options)
        server.nuxt = nuxt
        return nuxt.ready()
      })
      .catch((error) => {
        console.error('Error while rebuild the app:', error) // eslint-disable-line no-console
        process.exit(1)
      })
  }, 200)
  chokidar.watch(nuxtConfigFile, Object.assign({}, nuxt.options.watchers.chokidar, { ignoreInitial: true }))
    .on('all', build)
}

module.exports = nuxt