// Generated by CoffeeScript 1.10.0
(function() {
  var _, bodyParser, createControlServer, csrf, express, moment, morgan, multer, os, session;

  express = require('express');

  morgan = require('morgan');

  session = require('cookie-session');

  moment = require('moment');

  _ = require('lodash');

  bodyParser = require('body-parser');

  os = require('os');

  multer = require('multer');

  csrf = require('./csrf');

  createControlServer = function(app) {
    var api, csrfp, renderVars, saveConfigAndRedirectToSimulation, server, tmpUpload;
    server = express();
    server.set('view engine', 'pug');
    server.set('views', app.installDir + '/control-views');
    server.use(morgan('[CONTROL] :method :url :status :response-time ms - :res[content-length]'));
    server.use('/components', express["static"](app.installDir + '/node_modules'));
    server.use('/assets', express["static"](app.installDir + '/control-assets'));
    server.use(session({
      name: 'control_session',
      httpOnly: false,
      keys: ['123', '456']
    }));
    csrfp = csrf();
    server.use(csrfp);
    server.get('/', function(req, res) {
      return res.redirect('/devices');
    });
    renderVars = function(req) {
      var vars;
      vars = {
        app: app,
        moment: moment,
        _: _,
        req: req
      };
      if (req.csrfToken) {
        vars.csrfToken = req.csrfToken;
      }
      return vars;
    };
    server.get('/devices', function(req, res) {
      return res.render('device-list', _.defaults({
        devices: app.deviceManager.all(),
        networkInterfaces: os.networkInterfaces()
      }, renderVars(req)));
    });
    server.param('deviceId', function(req, res, next, id) {
      req.deviceId = id;
      if (req.device = app.deviceManager.byDeviceId(id)) {
        return next();
      } else {
        return res.status(404).end();
      }
    });
    server.get('/devices/details/:deviceId', function(req, res) {
      var data;
      data = {
        device: req.device,
        deviceId: req.deviceId
      };
      return res.render('device-details', _.defaults(data, renderVars(req)));
    });
    server.get('/devices/download/:deviceId', function(req, res) {
      var filename;
      filename = (req.device.displayName || req.deviceId) + '.json';
      res.setHeader('Content-Disposition', 'attachment; filename=' + filename);
      res.setHeader('Content-Type', 'application/json');
      return res.end(JSON.stringify(req.device));
    });
    tmpUpload = multer({
      storage: multer.memoryStorage()
    });
    server.post('/devices/upload', tmpUpload.single('data_file'), function(req, res) {
      var data, err, error, str;
      str = req.file.buffer.toString('utf8');
      try {
        data = JSON.parse(str);
        while (!data.deviceId || app.deviceManager.byDeviceId(data.deviceId)) {
          data.deviceId = Math.random().toString().substring(2);
        }
        app.deviceManager.add(data);
        return res.redirect('/devices/details/' + encodeURIComponent(data.deviceId));
      } catch (error) {
        err = error;
        return res.status(400).end('Error loading file: ' + String(err));
      }
    });
    server.get('/devices/details/:deviceId/start-simulation/:simulationId', csrfp.protect(), function(req, res) {
      req.device.plannedSimulationId = req.simulationId;
      return res.redirect('/devices/details/' + encodeURIComponent(req.deviceId));
    });
    server.get('/simulations', function(req, res) {
      return res.render('simulation-list', _.defaults({
        simulations: app.simulationManager.all()
      }, renderVars(req)));
    });
    server.param('simulationId', function(req, res, next, id) {
      req.simulationId = id;
      if (req.simulation = app.simulationManager.get(id)) {
        return next();
      } else {
        return res.status(404).end();
      }
    });
    server.get('/simulations/edit/:simulationId', function(req, res) {
      var data;
      data = {
        simulation: req.simulation,
        simulationId: req.simulationId
      };
      return res.render('edit-simulation', _.defaults(data, renderVars(req)));
    });
    saveConfigAndRedirectToSimulation = function(simulationId, res) {
      return app.saveConfig(function(err) {
        if (err != null) {
          return res.status(500).end('Failed to save configuration: ' + err);
        } else {
          return res.redirect('/simulations/edit/' + encodeURIComponent(simulationId));
        }
      });
    };
    server.post('/simulations/edit/:simulationId/set-title', bodyParser.urlencoded({
      extended: true
    }), function(req, res) {
      req.simulation.title = req.body.title || req.simulation.title;
      return saveConfigAndRedirectToSimulation(req.simulationId, res);
    });
    server.param('newTaskType', function(req, res, next, id) {
      req.newTaskType = id;
      return next();
    });
    server.get('/simulations/edit/:simulationId/add-task/:newTaskType', csrfp.protect(), function(req, res) {
      var task;
      task = {
        type: req.newTaskType,
        duration: 20
      };
      if (req.newTaskType === 'page') {
        task.page = 'average';
      }
      req.simulation.tasks.push(task);
      return saveConfigAndRedirectToSimulation(req.simulationId, res);
    });
    server.param('taskId', function(req, res, next, id) {
      req.taskId = parseInt(id);
      return next();
    });
    server.post('/simulations/edit/:simulationId/update-task/:taskId', bodyParser.urlencoded({
      extended: true
    }), function(req, res) {
      var task;
      task = req.simulation.tasks[req.taskId];
      if (task && task.type === req.body.type) {
        _.assign(task, req.body);
      }
      return saveConfigAndRedirectToSimulation(req.simulationId, res);
    });
    server.get('/simulations/edit/:simulationId/delete-task/:taskId', csrfp.protect(), function(req, res) {
      if (req.simulation.tasks[req.taskId] != null) {
        req.simulation.tasks.splice(req.taskId, 1);
      }
      return saveConfigAndRedirectToSimulation(req.simulationId, res);
    });
    server.get('/simulations/create', function(req, res) {
      var id;
      id = app.simulationManager.create();
      return saveConfigAndRedirectToSimulation(id, res);
    });
    return api = {
      init: function(cb) {
        var httpServer;
        cb = _.once(cb);
        httpServer = server.listen(app.config.controlServer.port);
        httpServer.once('listening', cb);
        return httpServer.once('error', cb);
      }
    };
  };

  module.exports = createControlServer;

}).call(this);
