#!/usr/bin/env node

var seaport = require('seaport')
  , cc = require('config-chain')
  , path = require('path')
  , fs = require('fs')
  , optimist = require('optimist')
  , debug = require('debug')('nodeport')


function extend(dest, src) {
  Object.keys(src).forEach(function (key) {
    dest[key] = src[key]
  })
}


var argv = optimist
  .describe('h', 'Seaport hostname')
  .alias('h', 'host')

  .describe('p', 'Seaport port (required)')
  .alias('p', 'port')

  .describe('q', 'Quiet mode')
  .alias('q', 'quiet')

  .describe('k', 'Seaport key file (see Seaport documentation)')
  .alias('k', 'key')

  .describe('help', 'Displays this help message')
  .argv


if (argv.help) {
  optimist.showHelp()
  return
}


var conf = cc( argv
             , cc.env('NODEPORT_')
             )

var file = cc.find('.nodeport')
if (file)
  conf.addString(fs.readFileSync(file))


// Defaults config
conf.root = {}
conf.root.host = '127.0.0.1'



if (!conf.get('port')) {
  throw 'NODEPORT: Missing seaport port'
}


var main
  , role
  , meta = {}

file = path.resolve(argv._[0] || '')

var pkgFile = path.basename(file) == 'package.json' ? file : path.join(file, 'package.json')
if (fs.existsSync( pkgFile )) {
  var pkg = require(pkgFile)

  if (pkg.nodeport) main = pkg.nodeport
  else if (pkg.main) main = pkg.main
  else if (pkg.scripts && pkg.scripts.start) main = pkg.scripts.start

  if (main) main = path.resolve(path.dirname(pkgFile), main)

  role = pkg.name + '@' + pkg.version
  if (pkg.seaport) extend(meta, pkg.seaport)
}

if (!main) {
  main = path.join(file, 'server.js')
  if (!fs.existsSync(main)) {
    main = file
  }
}

if (!role) {
  role = path.basename(file)
}

try {
  main = require(main)
} catch(err) {
  console.error('NODEPORT: Failed to load main')
  throw err
}

if (!main.listen) {
  throw 'NODEPORT Main must have a listen method'
}

var opts = conf.get('key') && JSON.parse(fs.readFileSync(path.resolve(conf.get('key')), 'utf8')) || {}

var ports = seaport.connect(conf.get('port'), conf.get('host'), opts)

var argMeta = conf.get('meta')
if (typeof argMeta === 'string') {
  argMeta = JSON.parse(fs.readFileSync(path.resolve(argMeta), 'utf8')) || {}
}
if (typeof argMeta === 'object') {
  extend(meta, argMeta)
}


var server = main.listen(ports.register(role, meta))


process.once('SIGINT', function () {
  debug('Got SIGINT, closeing')
  ports.close()
  if (typeof main.close === 'function') main.close()
  else if (typeof server.close === 'function') server.close()
})

@@ -600,24 +600,133 @@
 k', 'key')%0A%0A
+  .describe('r', 'Seaport role')%0A  .alias('r', 'role')%0A%0A  .describe('m', 'Main file')%0A  .alias('m', 'main')%0A%0A
   .describe(
@@ -1128,31 +1128,121 @@
 main
-%0A  , role%0A  , meta = %7B%7D
+ = conf.get('main')%0A  , role = conf.get('role')%0A  , meta = %7B%7D%0A%0Aif (main) main = path.resolve(process.cwd(), main)
 %0A%0Afi
@@ -1432,16 +1432,33 @@
 gFile)%0A%0A
+  if (!main) %7B%0A  
   if (pk
@@ -1489,16 +1489,18 @@
 odeport%0A
+  
   else i
@@ -1528,16 +1528,18 @@
 kg.main%0A
+  
   else i
@@ -1601,16 +1601,18 @@
 .start%0A%0A
+  
   if (ma
@@ -1664,17 +1664,38 @@
 , main)%0A
-%0A
+  %7D%0A%0A  if (!role) %7B%0A  
   role =
@@ -1724,16 +1724,21 @@
 version%0A
+  %7D%0A%0A
   if (pk

implement role and main options