'use strict';

var httpPort = 9090;
var express  = require('express');
var path     = require('path');
var fs       = require('fs');
var fetch    = require('fetch');
var cors     = require('cors');
var morgan   = require('morgan');
var UglifyJS = require("uglify-js");
var Hashes   = require('jshashes');
var minify   = require('minify');

var clientResourcesWeb = [];
var clientResources = {
	js: [],
	css: [],
	dss: []
};

var addClientResource = function(clientResource, resourceType) {
	clientResources[resourceType].push(clientResource);
};

var fetchHashResource = function(fetchEntry,cb) {
	var serverUrl = 'http://localhost:'+httpPort;
	var hashDigest = new Hashes.SHA1;
	fetch.fetchUrl(serverUrl + fetchEntry.url,function(err, meta, data) {
		if (err !== null) { return cb(err); }
		var assetHash = hashDigest.hex(''+data);
		clientResourcesWeb.push({
			url: fetchEntry.url,
			type: fetchEntry.type,
			hash: assetHash
		});
		cb(null);
	});
};

var fetchHashResources = function(fetchList, cb) {
	var resourceStack = fetchList;
	var resourceLoader = function() {
		resourceStack = resourceStack.slice(1);
		if (resourceStack.length === 0) {
			cb(null);
		} else {
			fetchHashResource(resourceStack[0],resourceLoader);
		}
	};
	fetchHashResource(resourceStack[0],resourceLoader);
};

var createClientResourceFetchList = function() {
	var fetchList = [];
	for (var clientResourceIdxJs in clientResources.js) {
		var urlJs = clientResources.js[clientResourceIdxJs];
		fetchList.push({url:urlJs,type:'js'});
	}
	for (var clientResourceIdxCss in clientResources.css) {
		var urlCss = clientResources.css[clientResourceIdxCss];
		fetchList.push({url:urlCss,type:'css'});
	}
	for (var clientResourceIdxCssData in clientResources.dss) {
		var urlCssData = clientResources.cssData[clientResourceIdxCssData];
		fetchList.push({url:urlCssData,type:'dss'});
	}
	return fetchList;
};

function renderTemplatePath(viewPath) {
	return function (req, res) {
		res.locals.query = req.query;
		var qi = req.url.indexOf('?');
		if (qi === -1) {
			qi = req.url.length;
		}
		res.render(viewPath + req.url.substring(req.route.path.length-1, qi));
	};
}

function renderIndex() {
	return function (req, res) {
		var inlineScript = UglifyJS.minify(__dirname+'/../../es5-ff-spa-loader.js');
		minify(__dirname+'/../../es5-ff-spa-loader.css', {}, function(err, data) {
			res.render('index', {
				inlineScript: inlineScript.code,
				inlineStyle: data
			});
		});
	};
}

// Add resources ORDERED per type
addClientResource('/static/module/jquery/jquery.js','js');
//addClientResource('/static/module/angular/angular.js','js');
//addClientResource('/static/module/angular-route/angular-route.js','js');
addClientResource('/static/module/bootstrap/css/bootstrap.css','css');
addClientResource('/static/module/bootstrap/js/bootstrap.js','js');
//addClientResource('/static/css/boot.css','css');
//addClientResource('/static/css/style.css','css');
//addClientResource('/static/js/example-app.js','js'); // deps: jquery,angular
//addClientResource('/static/js/controller/page-bar.js','js'); // deps: example-app.js 
//addClientResource('/static/js/controller/page-foo.js','js');
//addClientResource('/static/js/controller/page-index.js','js');

var appPath = '/test';
var server = express();
server.use(morgan('dev'));
server.use(cors({credentials: true, origin: '*',   exposedHeaders: ['X-My-Api']}));
server.set('view engine', 'ejs');
server.set('views',                                path.join(__dirname,'www_views'));
server.use(function(req, res, next) {              res.header('X-My-Api', 'noknok');next(); });
server.use(appPath+'/static',                      express.static(path.join(__dirname,'www_static')));
server.use(appPath+'/static/module/bootstrap',     express.static(path.join(__dirname,'../node_modules/bootstrap/dist')));
server.use(appPath+'/static/module/jquery',        express.static(path.join(__dirname,'../node_modules/jquery/dist')));
server.use(appPath+'/static/module/angular',       express.static(path.join(__dirname,'../node_modules/angular')));
server.use(appPath+'/static/module/angular-route', express.static(path.join(__dirname,'../node_modules/angular-route')));
server.get(appPath+'/static/spa-client-resources', function (req,res) {res.json({data: {resources: clientResourcesWeb}});});
server.get(appPath+'/static/spa-loader.css',       function (req,res) {res.sendFile('es5-ff-spa-loader.css', { root: path.join(__dirname, '/../../') });});
server.get(appPath+'/',                            function (req, res) {res.redirect(appPath+'/example-ui');});
server.get(appPath+'/example-ui/thtml/*',          renderTemplatePath('thtml/'));
server.get(appPath+'/example-ui',                  renderIndex());
server.get('/',                                    function (req, res) {res.redirect(appPath);});

var serverPort = null;

module.exports={
	start: function(cb) {
		serverPort = server.listen(httpPort);
		console.info('Server started on port '+httpPort);

		var res = createClientResourceFetchList();
		fetchHashResources(res, function(err) {
			cb(err);
			console.log('Total assets build: '+clientResourcesWeb.length);
		});		
	},
	stop: function(cb) {
		serverPort.close(cb);
	}
};