const util = require('util');
const path = require('path');
const EventEmitter = require('events').EventEmitter;
const extend = require('extend');
const semver = require('semver');
const findup = require('findup-sync');
const findCwd = require('./lib/find_cwd');
const findLocal = require('./lib/find_local');
const validExtensions = require('./lib/valid_extensions');

function Liftoff (opts) {
  opts = opts||{};
  var defaults = {
    cwdFlag: 'cwd',
    preloadFlag: 'require',
    completionFlag: 'completion',
    completions: null,
    cliPackage: null
  };
  if(opts.name) {
    if (!opts.processTitle) {
      opts.processTitle = opts.name;
    }
    if(!opts.configName) {
      opts.configName = opts.name+'file';
    }
    if(!opts.moduleName) {
      opts.moduleName = opts.name;
    }
  }
  if(!opts.processTitle) {
    throw new Error('You must specify a processTitle.');
  }
  if(!opts.configName) {
    throw new Error('You must specify a configName.');
  }
  if(!opts.moduleName) {
    throw new Error('You must specify a moduleName.');
  }
  if(!opts.configLocationFlag) {
    this.configLocationFlag = opts.configName;
  }
  extend(this, defaults, opts);
  console.log(this);
}
util.inherits(Liftoff, EventEmitter);

Liftoff.prototype.requireLocal = function (module, basedir) {
  try {
    var result = require(findLocal(module, basedir));
    this.emit('require', module, result);
    return result;
  } catch (e) {
    this.emit('requireFail', module, e);
  }
};

Liftoff.prototype.launch = function (fn, argv) {
  console.log(this);
  if(typeof fn !== 'function') {
    throw new Error('You must provide a callback function.');
  }
  if(!argv) {
    argv = require('minimist')(process.argv.slice(2));
  }
  process.title = this.processTitle;

  // parse command line options
  var cwd = argv[this.cwdFlag];
  var configLocation = argv[this.configLocationFlag];
  var preload = argv[this.preloadFlag]||[];
  var completion = argv[this.completionFlag];

  // run completions, if any available
  if (completion && this.completions) {
    return this.completions(completion);
  }

  // ensure preloads is an array
  if(!Array.isArray(preload)) {
    preload = [preload];
  }

  // if direct location of configFile has been specified,
  // use the folder it is located in as the cwd
  if(configLocation) {
    cwd = path.dirname(configLocation);
  }

  // build an environment
  var env = {
    settings: this,
    argv: argv,
    cwd: findCwd(cwd),
    preload: preload,
    validExtensions: null,
    configNameRegex: null,
    configPath: null,
    configBase: null,
    localPackage: null,
    modulePath: null
  };

  // preload any required modules
  preload.forEach(function (dep) {
    this.requireLocal(dep, env.cwd);
  }, this);

  // find the config file
  env.validExtensions = validExtensions();
  env.configNameRegex = this.configName+'{'+env.validExtensions.join(',')+'}';
  env.configPath = findup(env.configNameRegex, {cwd: env.cwd, nocase: true});

  // finish populating environment if a config was found
  if(env.configPath) {
    env.configBase = path.dirname(env.configPath);
    // attempt to load local module and package
    try {
      env.modulePath = findLocal(this.moduleName, env.configBase);
      env.modulePackage = require(findup('package.json', {cwd: env.modulePath}));

      // check for semver difference between cli and local installation
      if (semver.gt(this.cliPackage.version, env.modulePackage.version)) {
        this.emit('versionMismatch', this.cliPackage.version, this.modulePackage.version);
      }
    } catch (e) {}
  }

  // liftoff!
  fn.apply(env);
};

module.exports = Liftoff;

@@ -1168,37 +1168,16 @@
  opts);%0A
-  console.log(this);%0A
 %7D%0Autil.i

remove debugging line