text: /*jshint esversion: 6*/
  var express = require('express');
  var app = express();
  var crontab = require("./crontab");
  var restore = require("./restore");
  var moment = require('moment');
  
  var path = require('path');
  var mime = require('mime-types');
  var fs = require('fs');
  var busboy = require('connect-busboy'); // for file upload
  
  // include the routes
  var routes = require("./routes").routes;
  
  // set the view engine to ejs
  app.set('view engine', 'ejs');
  
  var bodyParser = require('body-parser');
  app.use(bodyParser.json());       // to support JSON-encoded bodies
  app.use(bodyParser.urlencoded({     // to support URL-encoded bodies
    extended: true
  }));
  app.use(busboy()); // to support file uploads
  
  // include all folders
  app.use(express.static(__dirname + '/public'));
  app.use(express.static(__dirname + '/public/css'));
  app.use(express.static(__dirname + '/public/js'));
  app.use(express.static(__dirname + '/config'));
  app.set('views', __dirname + '/views');
  
  // set host to 127.0.0.1 or the value set by environment var HOST
  app.set('host', (process.env.HOST || '127.0.0.1'));
  
  // set port to 8000 or the value set by environment var PORT
  app.set('port', (process.env.PORT || 8000));
  
  // root page handler
  app.get(routes.root, function(req, res) {
    // reload the database before rendering
  	crontab.reload_db();
  	// send all the required parameters
  	crontab.crontabs( function(docs){
  		res.render('index', {
  			routes : JSON.stringify(routes),
  			crontabs : JSON.stringify(docs),
  			backups : crontab.get_backup_names(),
  			env : crontab.get_env(),
        moment: moment
  		});
  	});
  });
  
  /*
  Handle to save crontab to database
  If it is a new job @param _id is set to -1
  @param name, command, schedule, logging has to be sent with _id (if exists)
  */
  app.post(routes.save, function(req, res) {
  	// new job
  	if(req.body._id == -1){
  		crontab.create_new(req.body.name, req.body.command, req.body.schedule, req.body.logging, req.body.mailing);
  	}
  	// edit job
  	else{
  		crontab.update(req.body);
  	}
  	res.end();
  });
  
  // set stop to job
  app.post(routes.stop, function(req, res) {
  	crontab.status(req.body._id, true);
  	res.end();
  });
  
  // set start to job
  app.post(routes.start, function(req, res) {
  	crontab.status(req.body._id, false);
  	res.end();
  });
  
  // remove a job
  app.post(routes.remove, function(req, res) {
  	crontab.remove(req.body._id);
  	res.end();
  });
  
  // set crontab. Needs env_vars to be passed
  app.get(routes.crontab, function(req, res, next) {
  	crontab.set_crontab(req.query.env_vars, function(err) {
  		if (err) next(err);
  		else res.end();
  	});
  });
  
  // backup crontab db
  app.get(routes.backup, function(req, res) {
  	crontab.backup();
  	res.end();
  });
  
  // This renders the restore page similar to backup page
  app.get(routes.restore, function(req, res) {
  	// get all the crontabs
  	restore.crontabs(req.query.db, function(docs){
  		res.render('restore', {
  			routes : JSON.stringify(routes),
  			crontabs : JSON.stringify(docs),
  			backups : crontab.get_backup_names(),
  			db: req.query.db
  		});
  	});
  });
  
  // delete backup db
  app.get(routes.delete_backup, function(req, res) {
  	restore.delete(req.query.db);
  	res.end();
  });
  
  // restore from backup db
  app.get(routes.restore_backup, function(req, res) {
  	crontab.restore(req.query.db);
  	res.end();
  });
  
  // export current crontab db so that user can download it
  app.get(routes.export, function(req, res) {
  	var file = __dirname + '/crontabs/crontab.db';
  
  	var filename = path.basename(file);
  	var mimetype = mime.lookup(file);
  
  	res.setHeader('Content-disposition', 'attachment; filename=' + filename);
  	res.setHeader('Content-type', mimetype);
  
  	var filestream = fs.createReadStream(file);
  	filestream.pipe(res);
  });
  
  // import from exported crontab db
  app.post(routes.import, function(req, res) {
  	var fstream;
  	req.pipe(req.busboy);
  	req.busboy.on('file', function (fieldname, file, filename) {
  		fstream = fs.createWriteStream(__dirname + '/crontabs/crontab.db');
  		file.pipe(fstream);
  		fstream.on('close', function () {
  			crontab.reload_db();
  			res.redirect(routes.root);
  		});
  	});
  });
  
  // import from current ACTUALL crontab
  app.get(routes.import_crontab, function(req, res) {
  	crontab.import_crontab();
  	res.end();
  });
  
  // get the log file a given job. id passed as query param
  app.get(routes.logger, function(req, res) {
  	_file = crontab.log_folder +"/"+req.query.id+".log";
  	if (fs.existsSync(_file))
  		res.sendFile(_file);
  	else
  		res.end("No errors logged yet");
  });
  
  // error handler
  app.use(function(err, req, res, next) {
  	var data = {};
  	var statusCode = err.statusCode || 500;
  
  	data.message = err.message || 'Internal Server Error';
  
  	if (process.env.NODE_ENV === 'development' && err.stack) {
  		data.stack = err.stack;
  	}
  
  	if (parseInt(data.statusCode) >= 500) {
  		console.error(err);
  	}
  
  	res.status(statusCode).json(data);
  });
  
  process.on('SIGINT', function() {
    console.log("Exiting crontab-ui");
    process.exit();
  })
  
  process.on('SIGTERM', function() {
    console.log("Exiting crontab-ui");
    process.exit();
  })
  
  app.listen(app.get('port'), app.get('host'), function() {
    console.log("Node version:", process.versions.node);
    fs.access(__dirname + "/crontabs/", fs.W_OK, function(err) {
      if(err){
        console.error("Write access to", __dirname + "/crontabs/", "DENIED.");
        process.exit(1);
      }
    });
    // If --autosave is used then we will also save whatever is in the db automatically without having to mention it explictly
    // we do this by watching log file and setting a on change hook to it
    if (process.argv.includes("--autosave")){
      crontab.autosave_crontab(()=>{});
      fs.watchFile(__dirname + '/crontabs/crontab.db', () => {
        crontab.autosave_crontab(()=>{
          console.log("Attempted to autosave crontab");
        });
      });
    }
    if (process.argv.includes("--reset")){
      console.log("Resetting crontab-ui");
      var crontabdb = __dirname + "/crontabs/crontab.db";
      var envdb = __dirname + "/crontabs/env.db";
  
      console.log("Deleting " + crontabdb);
      try{
        fs.unlinkSync(crontabdb);
      } catch (e) {
        console.log("Unable to delete " + crontabdb);
      }
  
      console.log("Deleting " + envdb);
      try{
        fs.unlinkSync(envdb);
      } catch (e) {
        console.log("Unable to delete " + envdb);
      }
  
      crontab.reload_db();
    }
  	console.log("Crontab UI is running at http://" + app.get('host') + ":" + app.get('port'));
  });
  