
import * as express from 'express';
import * as https from 'https';
import * as path from 'path';
import favicon = require ('serve-favicon');
import * as bodyParser from 'body-parser';
import cookieParser = require ('cookie-parser');
import * as socketio from 'socket.io';
import * as osenv from "osenv";
import * as pem from 'pem'
import * as Async from 'async'
import * as compression from 'compression';
import * as fs from 'fs';
import * as Shortid from "shortid"
import * as socketRoute from './views/api/sockRoute'

//import Procession from './process';

export const serverStart = () => {
	const app = express ();
	const port = process.env.PORT || 3000;
	const setupFolderName = '/Vpn.Email'
	const localPath = path.parse ( osenv.home() + setupFolderName )
	const keyFile = path.parse ( osenv.home() + setupFolderName + '/key.pem')
	const cretFile = path.parse ( osenv.home() + setupFolderName + '/cret.pem')
	const CertDays = 365 * 10;

	const createCertificate = ( CallBack ) => {
		Async.waterfall ([
			next => pem.createCertificate ({ days: CertDays, selfSigned: true }, next ),
			( key, next ) => {
				Async.parallel ([
					_next => fs.writeFile ( path.format ( keyFile ), key.serviceKey, { encoding: 'utf8'}, next ),
					_next => fs.writeFile ( path.format ( cretFile ), key.certificate, { encoding: 'utf8'}, next )
				], next )
			}
		], err => {
			if ( err )
				return CallBack ( err )
			CallBack ()
		})
		
	}

	const checkServerKeyFile = ( CallBack ) => {
		Async.parallel ([
			next => fs.access ( path.format ( keyFile ), next ),
			next => fs.access ( path.format ( cretFile ), next )
		], err => {
			if ( err ) {
				return createCertificate ( CallBack )
			}
			CallBack ()
		})
	}

	const checkLocal_SetupPath = ( CallBack ) => {
		let localPathString = path.format ( localPath );
		fs.access ( localPathString, err => {
			if ( err ) {
				
				return fs.mkdir ( localPathString, err1 => {
					if ( err1 )
						return CallBack ( err1 )
					return CallBack ()
				});
			}
			return CallBack ()
		})
	}

	Async.series ([
		next => checkLocal_SetupPath ( next ),
		next => checkServerKeyFile ( next )
	], err => {
		if ( err ) {
			console.log ("Vpn.email file system init error! vpn.email can't continue.", err )
			return process.exit (1)
		}
		// view engine setup
		const option = {
			key: fs.readFileSync ( path.format ( keyFile ), 'utf8' ),
			cert: fs.readFileSync ( path.format ( cretFile ), 'utf8')
		}
		app.set ( 'views', path.join ( __dirname, 'views' ));
		app.set ( 'view engine', 'pug' );
		app.use ( favicon ( __dirname + '/public/favicon.ico' ));
		app.use ( bodyParser.json ());
		app.use ( compression ()); //use compression
		app.use ( bodyParser.urlencoded ({ extended: false }));
		app.use ( cookieParser ());
		app.use ( require ( 'stylus' ).middleware ( path.join ( __dirname, 'public' )));
		app.use ( express.static ( path.join ( __dirname, 'public' )));
		app.get ( '/', ( req, res ) => {
			res.render( 'home', { title: 'home' });
		});
		const server = https.createServer ( option, app );
		const io = socketio ( server );

		socketRoute.sockRoute ( io )

		require ( './views/home/Route' )( app );
		require ( './views/firstRun/Route' )( app );
		require ( './views/config/Route' )({ 'io': io, 'app': app });
		
		require ( './views/api/Route' )({
			'app': app, 'io': io
		});
		

		app.use (( req, res, next ) => {
			var err = new Error( 'Not Found' );
			err.message = '404';
			next ( err );
		});


		server.listen ( port, () => {
			console.log ( 'Server start at: ' + port );
		});

		app.set ( 'online', true )
		module.exports = app;
		//const procession = new Procession ( app )
	})
}



