// Generated by CoffeeScript 1.8.0
var fs, getDotWeinreServerProperties, getTildeReplacement, nopt, optionDefaults, path, printHelp, printNoptError, replaceTilde, utils, weinre, _;

fs = require('fs');

path = require('path');

_ = require('underscore');

nopt = require('nopt');

utils = require('./utils');

weinre = require('./weinre');

optionDefaults = {
  httpPort: 8080,
  boundHost: 'localhost',
  verbose: false,
  debug: false,
  readTimeout: 5
};

exports.run = function() {
  var args, knownOpts, opts, parsedOpts, shortHands;
  knownOpts = {
    httpPort: Number,
    boundHost: String,
    verbose: Boolean,
    debug: Boolean,
    readTimeout: Number,
    deathTimeout: Number,
    help: Boolean
  };
  shortHands = {
    '?': ['--help'],
    'h': ['--help']
  };
  nopt.invalidHandler = printNoptError;
  parsedOpts = nopt(knownOpts, shortHands, process.argv, 2);
  if (parsedOpts.help) {
    printHelp();
  }
  args = parsedOpts.argv.remain;
  if (args.length !== 0) {
    printHelp();
  }
  delete parsedOpts.argv;
  opts = _.extend({}, optionDefaults, getDotWeinreServerProperties(), parsedOpts);
  if (opts.deathTimeout == null) {
    opts.deathTimeout = 3 * opts.readTimeout;
  }
  utils.setOptions(opts);
  return weinre.run(opts);
};

printNoptError = function(key, val, types) {
  return utils.exit("error with option '" + key + "', value '" + val + "'");
};

printHelp = function() {
  var version;
  version = weinre.getVersion();
  console.error("usage:   " + utils.Program + " [options]\nversion: " + version + "\n\noptions:\n    --httpPort     port to run the http server on        default: " + optionDefaults.httpPort + "\n    --boundHost    ip address to bind the server to      default: " + optionDefaults.boundHost + "\n    --verbose      print more diagnostics                default: " + optionDefaults.verbose + "\n    --debug        print even more diagnostics           default: " + optionDefaults.debug + "\n    --readTimeout  seconds to wait for a client message  default: " + optionDefaults.readTimeout + "\n    --deathTimeout seconds to wait to kill client        default: 3*readTimeout\n\n--boundHost can be an ip address, hostname, or -all-, where -all-\nmeans binding to all ip address on the current machine'\n\nfor more info see: http://people.apache.org/~pmuellr/weinre/");
  return process.exit();
};

getDotWeinreServerProperties = function() {
  var contents, fileName, key, line, lines, match, properties, val, _i, _len;
  properties = {};
  fileName = replaceTilde('~/.weinre/server.properties');
  if (!utils.fileExistsSync(fileName)) {
    return properties;
  }
  contents = fs.readFileSync(fileName, 'utf8');
  lines = contents.split('\n');
  for (_i = 0, _len = lines.length; _i < _len; _i++) {
    line = lines[_i];
    line = line.replace(/#.*/, '');
    match = line.match(/\s*(\w+)\s*:\s*(.+)\s*/);
    if (!match) {
      continue;
    }
    key = utils.trim(match[1]);
    val = utils.trim(match[2]);
    properties[key] = val;
  }
  return properties;
};

replaceTilde = function(fileName) {
  return fileName.replace('~', getTildeReplacement());
};

getTildeReplacement = function() {
  return process.env["HOME"] || process.env["USERPROFILE"] || '.';
};
