/*
 *
 *   Copyright 2016 RIFT.IO Inc
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *
 */

/**
 * Main skyquake module.
 * @module skyquake
 * @author Kiran Kashalkar <kiran.kashalkar@riftio.com>
 */

// Standard library imports for forking
var cluster = require("cluster");
var cpu = require('os').cpus().length;
var clusteredLaunch = process.env.CLUSTER_SUPPORT || false;
var constants = require('./framework/core/api_utils/constants');
// Uncomment for Replay support
// const Replay  = require('replay');
var freePorts = [];
for (var i = 0; i < constants.SOCKET_POOL_LENGTH; i++) {
	freePorts[i] = constants.SOCKET_BASE_PORT + i;
};


if (cluster.isMaster && clusteredLaunch) {
    console.log(cpu, 'CPUs found');
    for (var i = 0; i < cpu; i ++) {
    	var worker = cluster.fork();
    	worker.on('message', function(msg) {
	    	if (msg && msg.getPort) {
				worker.send({
					port: freePorts.shift()
				});
				console.log('freePorts after shift for worker', this.process.pid, ':', freePorts);
			} else if (msg && msg.freePort) {
				freePorts.unshift(msg.port);
				console.log('freePorts after unshift of', msg.port, 'for worker', this.process.pid, ':', freePorts);
			}
	    });
    }

    cluster.on('online', function(worker) {
        console.log("Worker Started pid : " + worker.process.pid);
    });
    cluster.on('exit', function(worker, code, signal) {
        console.log('worker ' + worker.process.pid + ' stopped');
    });
} else {
	// Standard library imports
	var argv = require('minimist')(process.argv.slice(2));
	var pid = process.pid;
	var fs = require('fs');
	var https = require('https');
	var http = require('http');
	var express = require('express');
	var session = require('express-session');
	var cors = require('cors');
	var bodyParser = require('body-parser');
	var _ = require('lodash');
	var reload = require('require-reload')(require);
	var Sockets = require('./framework/core/api_utils/sockets.js');

	require('require-json');

	// SSL related configuration bootstrap
	var httpServer = null;
	var secureHttpServer = null;

	var httpsConfigured = false;

	var sslOptions = null;

	var apiServer = argv['api-server'] ? argv['api-server'] : 'localhost';
	var uploadServer = argv['upload-server'] ? argv['upload-server'] : null;

	try {
		if (argv['enable-https']) {
			var keyFilePath = argv['keyfile-path'];
			var certFilePath = argv['certfile-path'];

			sslOptions = {
				key: fs.readFileSync(keyFilePath),
		    	cert: fs.readFileSync(certFilePath)
			};

			httpsConfigured = true;
		}
	} catch (e) {
		console.log('HTTPS enabled but file paths missing/incorrect');
		process.exit(code = -1);
	}

	var app = express();

	app.set('views', __dirname + '/framework/core/views');
	app.engine('html', require('ejs').renderFile);

	app.use(session({
	  secret: 'ritio rocks',
	  resave: true,
	  saveUninitialized: true
	}));
	app.use(bodyParser.json());
	app.use(cors());
	app.use(bodyParser.urlencoded({
		extended: true
	}));

	var socketManager = new Sockets();
	var socketConfig = {
		httpsConfigured: httpsConfigured
	};

	if (httpsConfigured) {
		socketConfig.sslOptions = sslOptions;
	}

	// Rift framework imports
	var constants = require('./framework/core/api_utils/constants');
	var skyquakeEmitter = require('./framework/core/modules/skyquakeEmitter');
	var navigation_routes = require('./framework/core/modules/routes/navigation');
	var socket_routes = require('./framework/core/modules/routes/sockets');
	var restconf_routes = require('./framework/core/modules/routes/restconf');
	var inactivity_routes = require('./framework/core/modules/routes/inactivity');
	var descriptor_routes = require('./framework/core/modules/routes/descriptorModel');
	var configuration_routes = require('./framework/core/modules/routes/configuration');
	var configurationAPI = require('./framework/core/modules/api/configuration');
	var userManagement_routes = require('./framework/core/modules/routes/userManagement');
	var projectManagement_routes = require('./framework/core/modules/routes/projectManagement');
	var session_routes = require('./framework/core/modules/routes/sessions');
	/**
	 * Processing when a plugin is added or modified
	 * @param {string} plugin_name - Name of the plugin
	 */
	function onPluginAdded(plugin_name) {
		// Load plugin config
		var plugin_config = reload('./plugins/' + plugin_name + '/config.json');

		// Load all app's views
		app.use('/' + plugin_name, express.static('./plugins/' + plugin_name + '/' + plugin_config.root));

		// Load all app's routes
		app.use('/' + plugin_name, require('./plugins/' + plugin_name + '/routes'));

		// Publish navigation links
		if (plugin_config.routes && _.isArray(plugin_config.routes)) {
			skyquakeEmitter.emit('config_discoverer.navigation_discovered', plugin_name, plugin_config);
		}

	}

	/**
	 * Serve jquery
	 */
	app.use('/jquery', express.static('./node_modules/jquery/dist/jquery.min.js'));
	/**
	 * Serve images
	 */
	app.use('/img', express.static('./framework/style/img'));

	/**
	 * Start listening on a port
	 * @param {string} port - Port to listen on
	 * @param {object} httpServer - httpServer created with http(s).createServer
	 */
	function startListening(port, httpServer) {
		var server = httpServer.listen(port, function () {
			var host = server.address().address;

			var port = server.address().port;

			console.log('Express server listening on port', port);
		});
		return server;
	}

	/**
	 * Initialize skyquake
	 */
	function init() {
		skyquakeEmitter.on('plugin_discoverer.plugin_discovered', onPluginAdded);
		skyquakeEmitter.on('plugin_discoverer.plugin_updated', onPluginAdded);
	}

	/**
	 * Configure skyquake
	 */
	function config() {
		// Conigure any globals
		process.env.NODE_TLS_REJECT_UNAUTHORIZED=0;

		// Configure navigation router
		app.use(navigation_routes);

		// Configure restconf router
		app.use(restconf_routes);

		//Configure inactivity route(s)
		app.use(inactivity_routes);

		// Configure global config with ssl enabled/disabled
		var globalConfig = {
			ssl_enabled: httpsConfigured,
			api_server: apiServer
		};

		if (uploadServer) {
			globalConfig.upload_server = uploadServer;
		}

		configurationAPI.globalConfiguration.update(globalConfig);

		// Configure configuration route(s)
		app.use(configuration_routes);

		//Configure descriptor route(s)
		app.use(descriptor_routes);

		//Configure user management route(s)
		app.use(userManagement_routes);

		//Configure project management route(s)
		app.use(projectManagement_routes);

		//Configure session route(s)
		app.use(session_routes);

		// app.get('/testme', function(req, res) {
		// 	res.sendFile(__dirname + '/index.html');
		// });

		// Configure HTTP/HTTPS server and populate socketConfig.
		if (httpsConfigured) {
			console.log('HTTPS configured. Will create 2 servers');
			secureHttpServer = https.createServer(sslOptions, app);
			// Add redirection on SERVER_PORT
			httpServer = http.createServer(function(req, res) {
				var host = req.headers['host'];
				host = host.replace(/:\d+$/, ":" + constants.SECURE_SERVER_PORT);

				res.writeHead(301, { "Location": "https://" + host + req.url });
    			res.end();
			});

			socketConfig.httpServer = secureHttpServer;
		} else {
			httpServer = http.createServer(app);
			socketConfig.httpServer = httpServer;
		}

		// Configure socket manager
		socketManager.configure(socketConfig);

		// Configure socket router
		socket_routes.routes(socketManager);
		app.use(socket_routes.router);

		// Serve multiplex-client
		app.get('/multiplex-client', function(req, res) {
			res.sendFile(__dirname + '/node_modules/websocket-multiplex/multiplex_client.js');
		});
	}

	/**
	 * Run skyquake functionality
	 */
	function run() {

		// Start plugin_discoverer
		var navigation_manager = require('./framework/core/modules/navigation_manager');
		var plugin_discoverer = require('./framework/core/modules/plugin_discoverer');

		// Initialize asynchronous modules
		navigation_manager.init();
		plugin_discoverer.init();

		// Configure asynchronous modules
		navigation_manager.config()
		plugin_discoverer.config({
			plugins_path: './plugins'
		});

		// Run asynchronous modules
		navigation_manager.run();
		plugin_discoverer.run();


		// Server start
		if (httpsConfigured) {
			console.log('HTTPS configured. Will start 2 servers');
			// Start listening on SECURE_SERVER_PORT (8443)
			var secureServer = startListening(constants.SECURE_SERVER_PORT, secureHttpServer);
		}
		// Start listening on SERVER_PORT (8000)
		var server = startListening(constants.SERVER_PORT, httpServer);

	}

	init();

	config();

	run();
}
