/**
 * Express based http & https server
 *
 * Requires express >= 4
 */

/*
var   common    = require ('./server/common'),
      authorize = require ('./server/authorization'),
      dbs       = require ('./server/dbs'),
      files     = require ('./server/files');
*/

const fs      = require ('fs'),
      http    = require ('http'),
      https   = require ('https'),
      express = require ('express'),
      session = require ('express-session'), // session management
      morgan  = require ('morgan'),		// logger
      //serveFavicon = require ('serve-favicon'),
      bodyParser = require ('body-parser');
      //MongoStore = require ('connect-mongo')(session); // uss mongodb as session storage

var app = express();

var http_port=8888;
	https_port=8889;

/*
 * Init
 */
/*ll
common   .init ();
authorize.init (common);
dbs      .init (common);
files    .init (common);
*/

// Security
app.disable ('x-powered-by'); // TODO: Disable Header information: Powerd by Express -> Information disclosure


/*
 * Route Control
 */

// Logger
app.use (morgan ('dev'));
//app.use(express.logger ( { format: 'default', stream: output_stream } ));

// Fastpaths
//app.use (serveFavicon (__dirname + '/public/favicon.ico'));

// Session Management
app.use (session({
    secret: 'adluhohks',
    resave: false,
    saveUninitialized: false,
    cookie: {
        maxAge: 30*24*3600*1000,    // TODO: ttl for session as well (Store)
        secure: false,              // true for https only
    },
    name: 'om.sid',
    //store: new MongoStore ({mongooseConnection: dbs.mongoose.connection, ttl: 30*24*3600}),   // mongoose + connect-mongo
    //store: new MemoryStore ({checkPeriod: 24*3600*1000}),   // memorystore
}));

// Args
app.use (bodyParser.json());
app.use (bodyParser.urlencoded({extended: true}));

// API
//var api_routes = express.Router(); // express app-object routing
//app.use ('/api', api_routes);

// Static Files
app.use (express.static(__dirname + '/public'));	// Allow server access to 'public' folder

// Other stuff is NOT authorized unless logged in
//app.use (authorize.genCheckAuthorized ('user'));

// Uploaded files
//app.use ('/uploads', express.static(__dirname + '/uploads'));

// Errors
// No error so far? Then it's a 404!
//app.use (function (req, res, next) { next (common.genError (404, req.url)); });
//app.use (routes.errorHandler (true)); /* true: show stack traces */ // TODO: Error Handler


/*
 * API
 */
/*
// API allowed for all
api_routes.post ('/login', authorize.login); // /api/login

// Validate all other API calls
api_routes.use (authorize.genCheckAuthorized ('user'));
api_routes.post ('/logout', authorize.logout);

function addRoutes (r) {
    for (var e in r.routes) {
        var params = r.routes[e].params ? "/" + r.routes[e].params : "";
        console.log ("Adding routes for /" + e + params + ":" +
                     (r.routes[e].get ? " get":" ") + (r.routes[e].post ? " post":" ") +
                     (r.routes[e].put ? " put":" ") + (r.routes[e].delete ? " delete":" "));
        if (r.routes[e].get)
            api_routes.get ('/' + e + params, r.routes[e].get);
        if (r.routes[e].post)
            api_routes.post ('/' + e + params, r.routes[e].post);
        if (r.routes[e].put)
            api_routes.put  ('/' + e + params, r.routes[e].put);
        if (r.routes[e].delete)
            api_routes.delete ('/' + e + params, r.routes[e].delete);
    }
}

addRoutes (dbs);
addRoutes (files);
*/

/*
 * Servers
 */

http.createServer (app) .listen (http_port, function () {
    console.log ("Express http server listening on port " + http_port);
});

/*
 * SSL certificates
 *
 * Keys + Certificate in current dir (not servable!)
 * to create (self-signed) SSL certs:
 *
 * openssl genrsa -out privatekey.pem 1024
 * openssl req -new -key privatekey.pem -out certrequest.csr
 * openssl x509 -req -in certrequest.csr -signkey privatekey.pem -out certificate.pem
 * rm certrequest.csr
 */

var options;
try {
    try {
	// In case it's a real certificate: add CA chain cersts (TODO: use array if required)
	/* Uncomment if real certificate is required and available
    var ca = fs.readFileSync ('keys/ca_cert.pem');
    } catch (e) {
	ca = undefined;
	console.log ("Note: Can't read CA bundle: "+e);
    }
    */
    options = {
	key: fs.readFileSync  ('keys/omkey.pem'),
	cert: fs.readFileSync ('keys/certificate.pem'),
	ca: ca
    };
    https.createServer (options, app) .listen (https_port, function () {
	console.log ("Express https server listening on port " + https_port);
    });
} catch (e) {
    console.log ("Note: Can't read SSL keys/certs: "+e+"\nDisabling https server");
}


/*
 * Uncaught Exceptions
 */

process.on ("uncaughtException", function (err) {
    console.error ("*** Uncaught Exception:");
    console.error (err.stack);
});
