// Generated by CoffeeScript 1.10.0
(function() {
  var App, app, args, argsjs, async, contentServer, controlServer, ddUpdater, defaultConfig, defaultsDeep, deviceManager, fs, opn, request, simulationManager, start, updateChecker;

  fs = require('fs');

  controlServer = require('./control-server');

  contentServer = require('./content-server');

  deviceManager = require('./device-manager');

  simulationManager = require('./simulation-manager');

  updateChecker = require('./update-checker');

  ddUpdater = require('./dd-updater');

  defaultsDeep = require('lodash').defaultsDeep;

  async = require('async');

  argsjs = require('args.js');

  opn = require('opn');

  request = require('request');

  defaultConfig = require('./default-config.json');

  App = (function() {
    function App(configPath) {
      this.installDir = __dirname + '/..';
      this.packageInfo = require(this.installDir + '/package.json');
      this.configPath = configPath;
    }

    App.prototype.initNewConfig = function(cb) {
      return fs.open(this.configPath, 'wx', function(err, fd) {
        if (err != null) {
          return cb(err);
        }
        return fs.write(fd, '{}', 'utf8', function(err) {
          return fs.close(fd, function(closeErr) {
            if (err != null) {
              return cb(err);
            }
            return cb(closeErr);
          });
        });
      });
    };

    App.prototype.init = function(cb) {
      return this.reloadConfig((function(_this) {
        return function(err) {
          if (err != null) {
            return cb(err);
          }
          _this.simulationManager = simulationManager(_this);
          return async.each([_this.controlServer = controlServer(_this), _this.contentServer = contentServer(_this), _this.deviceManager = deviceManager(_this), _this.updateChecker = updateChecker(_this), _this.ddUpdater = ddUpdater(_this)], function(service, cb) {
            return service.init(cb);
          }, cb);
        };
      })(this));
    };

    App.prototype.reloadConfig = function(cb) {
      return fs.readFile(this.configPath, {
        encoding: 'utf8'
      }, (function(_this) {
        return function(err, configStr) {
          var error;
          if (err != null) {
            return cb(err);
          }
          try {
            _this.config = JSON.parse(configStr);
          } catch (error) {
            err = error;
            return cb(err);
          }
          _this.config = defaultsDeep(_this.config, defaultConfig);
          return cb(null);
        };
      })(this));
    };

    App.prototype.saveConfig = function(cb) {
      var configStr;
      configStr = JSON.stringify(this.config, null, '  ');
      return fs.writeFile(this.configPath, configStr, {
        encoding: 'utf8'
      }, cb);
    };

    return App;

  })();

  args = argsjs.parse([
    {
      id: 'configFile',
      name: 'config file',
      defaultValue: 'config.json'
    }, {
      id: 'initConfig',
      flags: ['i', 'init'],
      isSwitch: true,
      help: 'Initialize a new configuration file'
    }, {
      id: 'help',
      isSwitch: true,
      special: true,
      flags: ['h', 'help'],
      validator: function(val, data) {
        console.log('usersim ' + data.parser.help());
        return process.exit();
      }
    }, {
      id: 'gui',
      flags: ['gui', 'g'],
      isSwitch: true,
      help: 'Open control interface in default web browser'
    }
  ]);

  app = new App(args.configFile);

  start = function() {
    return app.init(function(err) {
      if (err != null) {
        console.error(err);
        return process.exit();
      } else {
        console.log('Ready!');
        if (args.gui) {
          return opn('http://localhost:' + app.config.controlServer.port + '/');
        }
      }
    });
  };

  if (args.initConfig) {
    app.initNewConfig(function(err) {
      if (err != null) {
        return console.error('Error initializing configuration: ' + err);
      } else {
        console.log('Configuration initialized');
        return start();
      }
    });
  } else {
    start();
  }

}).call(this);
